Здравствуйте, ArtDenis, Вы писали:
AD>Представим себе, что мы бы отказались от пропертей. Тогда таблица свойств объекта получилась бы примерно такой: AD>
Здравствуйте, EvilChild, Вы писали:
EC>Здравствуйте, Kore Sar, Вы писали:
KS>>А преобразовать к необходимому типу? EC>Можешь привести пример рабочего кода?
Здравствуйте, EvilChild, Вы писали:
EC>Например есть IEnumerable<string>, надо вернуть IEnumerable<object>. EC>Тупо return значение типа IEnumerable<string> из функции с типом возвращаемого значения IEnumerable<object> не прокатит. EC>Вот yield return единственный известный мне выход.
Достаточно один раз написать.
IEnumerable<T> Cast<T>(IEnumerable src) where T : class
{
foreach (object item in src)
yield return (T)item;
// Вариант:
// T typedItem = item as T;
// if (item != null)
// yield return (T)item;
}
В linq2objects что то подобное есть ввиде extension method.
А вобще необходимость подобных финтов, да еще и в большом количестве это повод задуматься.
Здравствуйте, AndrewVK, Вы писали:
AVK>Достаточно один раз написать. AVK>
AVK>IEnumerable<T> Cast<T>(IEnumerable src) where T : class
AVK>{
AVK> foreach (object item in src)
AVK> yield return (T)item;
AVK> // Вариант:
AVK> // T typedItem = item as T;
AVK> // if (item != null)
AVK> // yield return (T)item;
AVK>}
AVK>
AVK>В linq2objects что то подобное есть ввиде extension method.
То, о чём я говорил прямо противоположно приведённому тобой коду. Но это не принципиально.
AVK>А вобще необходимость подобных финтов, да еще и в большом количестве это повод задуматься.
Задуматься о чём?
Ты как решаешь проблему отсутствия константности в .NET? Или у тебя нет такой проблемы?
Здравствуйте, EvilChild, Вы писали:
EC>То, о чём я говорил прямо противоположно приведённому тобой коду.
А если присмотреться повнимательнее?
AVK>>А вобще необходимость подобных финтов, да еще и в большом количестве это повод задуматься. EC>Задуматься о чём?
О дизайне.
EC>Ты как решаешь проблему отсутствия константности в .NET?
При чем тут константность? Речь о ковариантности дженериков по type parameter.
Здравствуйте, AndrewVK, Вы писали:
AVK>А если присмотреться повнимательнее?
Вот, что мне нужно было:
private static IEnumerable<TOutput> Cast<TInput, TOutput>(IEnumerable<TInput> coll)
where TInput : TOutput
{
foreach (TInput item in coll)
yield return (TOutput)item;
}
Вот пример использования:
IEnumerable<object> test = Cast<string, object>(new string[] {"1", "2"});
AVK>О дизайне.
Поясню что я имел в виду.
Есть readonly интерфейс IReadonly и класс его реализующий SomeClass : IReadonly.
SomeClass объявлен приватно в другом классе SomeAggregate.
Клиенты класса SomeAggregate знают только об IReadonly.
В экземпляре класса SomeAggregate есть контейнер экземпляров типа SomeClass, который надо вернуть как IEnumerable<IReadonly>.
Именно для этого случая мне понадобилась ковариантность, причём она здесь совершенно безопасна.
Здравствуйте, _FRED_, Вы писали:
_FR>К тому же твой пример ещё и не скомпилится ;о)
Ты пробовал? Каким компилятором?
Microsoft (R) Visual C# 2005 Compiler version 8.00.50727.42 компилит мой код на ура.
Здравствуйте, _FRED_, Вы писали:
_FR>Так как IEnumerable<TInput> "унаследован" от IEnumerable, то версия AndrewVK "общее" и полностью покрывает твою. Проверь
Здравствуйте, AndrewVK, Вы писали:
EC>>Именно для этого случая мне понадобилась ковариантность, причём она здесь совершенно безопасна.
AVK>Не совсем так. Readonly недостаточно для безопасности ковариантности, нужно еще отсутствие параметров методов с типами из type arguments.
В моём случае (применительно к возвращаемому значению) безопасна.
По поводу методов согласен.
Твоё замечание относительно дизайна после моего уточнения остаётся в силе?
Если да, то можешь пояснить, что именно не нравится?
Здравствуйте, EvilChild, Вы писали:
EC>Твоё замечание относительно дизайна после моего уточнения остаётся в силе? EC>Если да, то можешь пояснить, что именно не нравится?
Лучше сделать элементы immutable на самом деле, а не за счет одного из интерфейсов.
Здравствуйте, _FRED_, Вы писали:
_FR>Так как IEnumerable<TInput> "унаследован" от IEnumerable, то версия AndrewVK "общее" и полностью покрывает твою. Проверь
Есть ещё одно отличие, на мой взгляд принципиальное в контексте обсуждаемой фичи.
Код Андрея более универсален и позволяет делать как upcast, так и downcast,
мой же только upcast, что даёт статическую гарантию успешного приведения, т.е. делает ровно то,
что от него требуется для решения этой задачи и его сложнее использовать неправильно.
Даже если ты перепутаешь порядок типов при вызове функции, то компилятор тебе об этом сообщит.
В общем при помещении этого кода в библиотеку я бы сделал 2 функции StaticCast & DynamicCast.
Здравствуйте, AndrewVK, Вы писали:
_FR>>Так как IEnumerable<TInput> "унаследован" от IEnumerable, то версия AndrewVK "общее" и полностью покрывает твою. Проверь
AVK>Не совсем. Там есть еще констрейнт.
Здравствуйте, EvilChild, Вы писали:
EC>Здравствуйте, mogadanez, Вы писали:
M>>а мы проперти с маленькой буквы пишем вот_так_вот EC>Ужас какой. Не диссонирует с библиотечным кодом?
В этом есть офигенный плюс как раз....
видно где наш код где ВасиПупкина...
на_фоне_нашего кода ПрыгающийКодВасиПупкина выглядит как ахтунг