Is there a way to cast generic lists to lists of interface/base class types?

こ雲淡風輕ζ 提交于 2019-12-04 14:56:51

The problem is with the method, not with how it's called.....

void PrintProperties<SP>(IEnumerable<SP> list) where SP: ISpecialProperties
{
    foreach (var item in list)
    {
        Console.WriteLine("{0} {1}", item.Prop1, item.Prop2);
    }
}

The reason it fails is because generics don't exhibit variance in C# (yet).

As for the fix for IEnumerable<T>, however, try this:

public static IEnumerable<TBase> SafeConvert<TBase, TDerived>(IEnumerable<TDerived> source)
    where TDerived : TBase
{
    foreach (TDerived element in source)
    {
        yield return element; // Implicit conversion to TBase
    }
}

EDIT: The other existing answer is better than the above for this particular case, but I'll leave this here as a generally useful thing if you do actually need to "convert" the sequence.

You can just use a foreach on the lists you have. The foreach does a built in cast. So if you take the loop out of the function you can write something like

List<Test> myList = new List<Test>();
for (int i = 0; i < 5; i++)
{
   myList.Add(new Test());
}

foreach (IDoSomething item in myList)
{
   item.DoSomething();
}

What you want is called "interface covariance" and is not supported by C# at the moment. You can read about it on Eric Lippert's blog.

This doesn't answer your question (or the point of the exercise I guess :), but I'd just use reflection in this case by attaching special attributes to the properties of interest.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!