Как создать список базовых классов, используя список вложенных классов через универсальный без приведения - PullRequest
3 голосов
/ 25 марта 2019

Я хотел бы иметь метод расширения для ICollection<T2>, который возвращается ко мне IReadOnlyCollection<T1>.Все это мне нужно для того, чтобы не повторяться в коде.У меня есть следующий код:

public static IReadOnlyCollection<T1> All<T1, T2>(this ICollection<T2> storage) where T1 : T2
{
    if (storage.Count > 0)
    {
        return new List<T1>(storage);
    }
    else
    {
        return new List<T1>();
    }
}

Но, к сожалению, он не компилируется.Итак, давайте посмотрим на несколько более простой пример выше:

public interface IDatabase {}
public class Database : IDatabase, IDisposable {}

public static IReadOnlyCollection<T1> All<T1, T2>(this ICollection<T2> storage) where T2 : T1 where T1 : new()
{
    // compiles
    List<Database> derivedList = new List<PublishedDatabase>();
    List<IDatabase> baseList = new List<IPublishedDatabase>(derivedList);

    // doesn't compile
    // with casting it works
    List<T2> derivedListT = new List<T2>();
    List<T1> baseList1T = new List<T1>(derivedListT/* as IEnumerable<T1>*/);

    //...
}

Могу ли я создать список базовых классов, используя список вложенных классов через универсальный без приведения?

Ответы [ 2 ]

1 голос
/ 25 марта 2019

Я, возможно, неправильно понимаю ограничения здесь, но вы можете предварительно использовать dynamic до hoodwink анализаторы

public static IReadOnlyCollection<T1> All<T1, T2>(this ICollection<T2> storage) where T2: T1
{
    dynamic temp = storage;
    return new ReadOnlyCollection<T1>(new List<T1>(temp));
}

...

var list = new List<SomeChild>()
               {
                  new SomeChild()
               };

var interfaces = list.All<ISomeBase, SomeChild>();

Примечание : Если ваши анализаторы кода жалуются на приведение, вы могли бы подумать, что они будут жаловаться еще сильнее на dynamic ... Также совершенно не проверено, и, вероятно, лучший способ сделать это

0 голосов
/ 25 марта 2019

Вы можете упростить код для метода расширения следующим образом:

public static IReadOnlyCollection<T1> All<T1>(this ICollection<T1> storage)
        {
            if(storage.Count > 0)
            {
                return new List<T1>(storage);
            }
            else
            {
                return new List<T1>();
            }
        }

и тогда вы можете назвать это так:

public static void Run()
        {
           ICollection<IDatabase> databases= new List<IDatabase>(){ new Database()};
           databases.All();
        }
...