将List <MyObject>转换为IEnumerable <MyInterface>

Hab*_*nte 2 c# ienumerable casting list

我还在学习一些这样的c#东西,我找不到这个问题的答案.假设我有一个MyObject实现MyInterface的列表

public class MyObject : IMyInterface { ...}

public List<MyObject> MyObjectList;
Run Code Online (Sandbox Code Playgroud)

如何IEnumerable<IMyInterface>使用MyObjectList的内容返回?

我的意思是,现在我有这个:

List<IMyInterface> temp = new List<IMyInterface>();
foreach (MyObject obj in MyObjects) temp.Add(obj);
return (IEnumerable<IMyInterface>)temp;
Run Code Online (Sandbox Code Playgroud)

但是有必要创建一个这样的新列表吗?

谢谢.

Jon*_*eet 6

如果您使用的是.NET 3.5,最简单的方法是:

return MyObjects.Cast<IMyInterface>();
Run Code Online (Sandbox Code Playgroud)

你并不需要创建所有内容的副本-但直到C#4出来与它的通用接口方差,你坚持做的事情是这样的.

如果您仍在使用.NET 2.0,则可以轻松地执行类似的操作:

public static IEnumerable<TResult> SafeCast<TSource, TResult>
    (IEnumerable<TSource> source) where TResult : TSource
{
    foreach (TSource item in source)
    {
        yield return item;
    }
}
Run Code Online (Sandbox Code Playgroud)

(注意,这不会检查是否为sourcenull;要正确执行此操作,由于迭代器块的延迟执行,您需要两个方法.)

然后使用:

return SafeCast<MyObject, IMyInterface>(MyObjects);
Run Code Online (Sandbox Code Playgroud)

可以使它更像LINQ版本,如下所示:

public static IEnumerable<T> SafeCast<T>(IEnumerable source)
{
    foreach (T item in source)
    {
        yield return item;
    }
}

return SafeCast<IMyInterface>(MyObjects);
Run Code Online (Sandbox Code Playgroud)

这有编译时的安全性 - 它不会阻止你尝试将a List<string>转换IEnumerable<Guid>为例如.