C# 演员名单<;T>;-协方差/逆变问题
鉴于以下类型:C# 演员名单<;T>;-协方差/逆变问题,c#,.net,.net-2.0,covariance,contravariance,C#,.net,.net 2.0,Covariance,Contravariance,鉴于以下类型: public interface IMyClass { } public class MyClass : IMyClass { } 我想知道如何将列表转换为列表?我不完全清楚协变/逆变的主题,但我明白,我不能简单地抛出名单,因为这一点 我只能想出这个微不足道的解决办法;缺乏优雅,浪费资源: ... public List<IMyClass> ConvertItems(List<MyClass> input) { var result = new L
public interface IMyClass { }
public class MyClass : IMyClass { }
我想知道如何将列表
转换为列表
?我不完全清楚协变/逆变的主题,但我明白,我不能简单地抛出名单,因为这一点
我只能想出这个微不足道的解决办法;缺乏优雅,浪费资源:
...
public List<IMyClass> ConvertItems(List<MyClass> input)
{
var result = new List<IMyClass>(input.Count);
foreach (var item in input)
{
result.Add(item);
}
return result;
}
....
。。。
公共列表项(列表输入)
{
var结果=新列表(input.Count);
foreach(输入中的变量项)
{
结果.添加(项目);
}
返回结果;
}
....
如何以更优雅/高效的方式解决此问题
(请注意,我需要.NET 2.0解决方案,但为了完整性,我也很乐意看到使用较新框架版本的更优雅的解决方案。)最简单的方法可能是使用: 在.NET 4.0中,由于
IEnumerable
的协方差性,您可以直接使用ToList
,而无需中间转换:
var converted=original.ToList();
(.NET 3.5解决方案)
List List=新列表{…};
List converted=List.Cast().ToList();
它需要是一个列表吗?IEnumerable
解决方案可能更有效:
public IEnumerable<IMyClass> ConvertItems(List<MyClass> input)
{
foreach (var item in input)
{
yield return (IMyClass)item;
}
}
public IEnumerable可转换项(列表输入)
{
foreach(输入中的变量项)
{
收益率返还(IMyClass)项目;
}
}
这是对协方差的偷偷使用;非常好。converted是一个IEnumerable
而不是一个列表
OP问“我如何才能将…转换为列表
”,而你不是转换为列表
,而是一个IEnumerable
@CodeInChaos:没错,这是我的第一个版本,最近我切换到了IEnumerable
。向后滚。值得一提的是,使用IEnumerable解决方案不一定需要这样做。该方法只需执行返回输入代码>。这将意味着底层对象仍然是列表,因此您可以返回到它——这是您在上述方法中没有发现的问题。但是协方差意味着直接转换到IEnumerable
是非常可能的。不确定这是否是一个新的变化,因为这个答案是7年前首次提出的。我不了解c#的历史,但它现在肯定是有效的
List<IMyClass> converted = original.ConvertAll<IMyClass>(
delegate (MyClass x) { return x; });
var converted = original.Cast<IMyClass>().ToList();
var converted = original.OfType<IMyClass>().ToList();
var converted = original.Select(x => (IMyClass) x).ToList();
var converted = original.ToList<IMyClass>();
List<MyClass> list = new List<MyClass> { ... };
List<IMyClass> converted = list.Cast<IMyClass>().ToList();
public IEnumerable<IMyClass> ConvertItems(List<MyClass> input)
{
foreach (var item in input)
{
yield return (IMyClass)item;
}
}