covariant return types
От: Codealot Земля  
Дата: 28.10.24 17:15
Оценка:
С каких-то пор, такой код стал работать:
abstract class Class1
{
    public abstract IEnumerator<Class1> GetItems();
}

class Class2 : Class1
{
    public override IEnumerator<Class2> GetItems()
    {
        throw new NotImplementedException();
    }
}

А вот такой — по прежнему нет:
class Class3 : IEnumerable<Class3>
{
    public IEnumerator<Class3> GetEnumerator()
    {
        throw new NotImplementedException();
    }
}

Кто-нибудь в курсе почему?
Ад пуст, все бесы здесь.
Re: covariant return types
От: m2user  
Дата: 28.10.24 17:49
Оценка:
C>Кто-нибудь в курсе почему?

А почему он должен работать, если IEnumerable имплементирован не полностью?
Так компилируется (на .NET 4.7.2):
class Class3 : IEnumerable<Class3>
{
    public IEnumerator<Class3> GetEnumerator()
    {
        throw new NotImplementedException();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }
}
Re[2]: covariant return types
От: Codealot Земля  
Дата: 28.10.24 17:51
Оценка:
Здравствуйте, m2user, Вы писали:

M>А почему он должен работать, если IEnumerable имплементирован не полностью?


По твоей логике, в Class2 базовый класс тоже "имплементирован не полностью".
Ад пуст, все бесы здесь.
Отредактировано 28.10.2024 17:52 Codealot . Предыдущая версия .
Re[3]: covariant return types
От: m2user  
Дата: 28.10.24 18:04
Оценка:
C>По твоей логике, в Class2 базовый класс тоже "имплементирован не полностью".

На 4.7.2 ошибка, что "target runtime does not support covariant type in overrides".
Как поддержка "covariant type in overrides" по твоему связана с необходимостью определить Enumerable.GetEnumerator?
Re[4]: covariant return types
От: Codealot Земля  
Дата: 28.10.24 18:07
Оценка:
Здравствуйте, m2user, Вы писали:

M>На 4.7.2 ошибка, что "target runtime does not support covariant type in overrides".

M>Как поддержка "covariant type in overrides" по твоему связана с необходимостью определить Enumerable.GetEnumerator?

Ну так у тебя версия древняя. Зачем ты стал на ней проверять?
Начиная с какой-то версии, ковариантность в классах уже работает.
Ад пуст, все бесы здесь.
Re[3]: covariant return types
От: hi_octane Беларусь  
Дата: 28.10.24 18:07
Оценка: +1
C>По твоей логике, в Class2 базовый класс тоже "имплементирован не полностью".
Полностью, иначе бы компилятор ругнулся. Ни Class1 ни Class2 не наследуют IEnumerable, поэтому к ним у компилятора другое отношение. Учитывая время вопроса — овертаймишь небось?
Re[4]: covariant return types
От: Codealot Земля  
Дата: 28.10.24 18:17
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>Полностью, иначе бы компилятор ругнулся. Ни Class1 ни Class2 не наследуют IEnumerable, поэтому к ним у компилятора другое отношение.


Раньше ругался, нужно было точное совпадение сигнатуры. Начиная с какой-то версии, достаточно совместимой сигнатуры. Возвращаемый тип можно изменить, если он более derived.
Но это только в классах. В интерфейсах — нет.
Вопрос — почему?

_>Учитывая время вопроса — овертаймишь небось?


У меня — середина дня. Про разные зоны времени никогда не слышал?
Ад пуст, все бесы здесь.
Отредактировано 28.10.2024 18:32 Codealot . Предыдущая версия .
Re[5]: covariant return types
От: m2user  
Дата: 28.10.24 18:33
Оценка:
C>Ну так у тебя версия древняя. Зачем ты стал на ней проверять?

Чтобы сравнить работу на старых и на новых версиях .NET.

C>Начиная с какой-то версии, ковариантность в классах уже работает.


Я кажется понял твой вопрос, только пример должен быть таким:

interface Class1
{
    IEnumerator<Class1> GetItems();
}

class Class2 : Class1
{
    public IEnumerator<Class2> GetItems()
    {
        throw new NotImplementedException();
    }
}


Почему с интерфейсом не компилит
Re[6]: covariant return types
От: Codealot Земля  
Дата: 28.10.24 18:37
Оценка:
Здравствуйте, m2user, Вы писали:

M>Я кажется понял твой вопрос, только пример должен быть таким:


Ну да, можно и так. Принцип тот же самый.
Ад пуст, все бесы здесь.
Re[7]: covariant return types
От: m2user  
Дата: 28.10.24 19:37
Оценка:
C>Ну да, можно и так. Принцип тот же самый.

Видимо ты имеешь в виду, что IEnumerator<Class3> GetEnumerator() и IEnumerator IEnumerable.GetEnumerator() можно было бы имплементировать одним методом.
Про covariant returns types пишут, что для интерфейсов эту фичу планировалось сделать позднее чем для классов
https://stackoverflow.com/questions/65230700/c-sharp-9-0-covariant-return-types-and-interfaces#comment115321098_65230700
Re[8]: covariant return types
От: Codealot Земля  
Дата: 28.10.24 19:50
Оценка:
Здравствуйте, m2user, Вы писали:

M>Видимо ты имеешь в виду, что IEnumerator<Class3> GetEnumerator() и IEnumerator IEnumerable.GetEnumerator() можно было бы имплементировать одним методом.


Я о том, что нет никаких причин, чтобы правила имплементации для абстрактных методов и деклараций методов в интерфейсах были разными. Во всем остальном там нет больших различий.

M>Про covariant returns types пишут, что для интерфейсов эту фичу планировалось сделать позднее чем для классов

M>https://stackoverflow.com/questions/65230700/c-sharp-9-0-covariant-return-types-and-interfaces#comment115321098_65230700

Это было 4 года назад. Похоже, что просто забили
Ад пуст, все бесы здесь.
Re[5]: covariant return types
От: hi_octane Беларусь  
Дата: 28.10.24 20:29
Оценка: 9 (1)
C>Но это только в классах. В интерфейсах — нет.
C>Вопрос — почему?
Может про интерфейсы команда шарпа думала что методы интерфейса вместе связаны, и хотела сохранить некую консистентность между ними И потому сделали ковариантность возвращаемых значений пачке методов через out T. Наверное их идея была в том, что класс реализует внутри себя максимально специфичную версию, а пользователь уж выбирает подходящего предка.

Кстати, если иерархия будет Class2 : (Class1 : IA<object>), всё равно пример правильно отработает. Но в "сложной иерархии" с out и без out поведение будет разное.

using System;
using System.Collections;
using System.Collections.Generic;

interface IA<out T>
{
    T GetT();
}

class Class2 : IA<string>
{
    public string GetT() => "str";
}

public class HelloWorld
{
    public static void Main(string[] args)
    {
         Class2 c = new();
         IA<object> ia = c; //кому нужен object - тот использует object
         Console.WriteLine(ia.GetT());
    }
}


C>У меня — середина дня. Про разные зоны времени никогда не слышал?

А, ну значит всё наоборот, эт я с трудом догоняю...
Re[6]: covariant return types
От: Codealot Земля  
Дата: 28.10.24 20:41
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>Может про интерфейсы команда шарпа думала что методы интерфейса вместе связаны, и хотела сохранить некую консистентность между ними


Да не. Судя по спеке, которую нашел m2user, такую фичу они рассматривали, но потом просто забыли /забили. Бардак-с.
Ад пуст, все бесы здесь.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.