可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Given the following types:
public interface IMyClass { } public class MyClass : IMyClass { }
I wonder how can I convert a List<MyClass> to a List<IMyClass>? I am not completely clear on the covariance/contravariance topics, but I understand that I cannot just plainly cast the List because of that.
I could come up with this trivial solution only; lacking any elegance, wasting resources:
... public List<IMyClass> ConvertItems(List<MyClass> input) { var result = new List<IMyClass>(input.Count); foreach (var item in input) { result.Add(item); } return result; } ....
How can you solve it in a more elegant/performant way?
(Please, mind that I need .NET 2.0 solution, but for completeness, I would be happy to see the more elegant solutions using newer framework versions, too.)
回答1:
The simplest way is probably to use ConvertAll:
List<IMyClass> converted = original.ConvertAll<IMyClass>(x => x);
Even if you're using .NET 2, you can use lambda syntax if you're using VS2008 or higher. Otherwise, there's always anonymous methods:
List<IMyClass> converted = original.ConvertAll<IMyClass>( delegate (MyClass x) { return x; });
In .NET 3.5 you could use LINQ with Cast, OfType or even just Select:
var converted = original.Cast<IMyClass>().ToList(); var converted = original.OfType<IMyClass>().ToList(); var converted = original.Select(x => (IMyClass) x).ToList();
In .NET 4.0 you can use ToList directly without an intermediate cast, due to the covariance of IEnumerable<T>:
var converted = original.ToList<IMyClass>();
回答2:
Does it need to be a list? An IEnumerable solution could be more efficient:
public IEnumerable<IMyClass> ConvertItems(List<MyClass> input) { foreach (var item in input) { yield return (IMyClass)item; } }
回答3:
(.NET 3.5 solution)
List<MyClass> list = new List<MyClass> { ... }; List<IMyClass> converted = list.Cast<IMyClass>().ToList();