集合的隐式转换

本周我遇到了关于集合中C#的隐式转换的问题。 虽然这(使用implicit )可能不是我们的最终方法,但我想至少完成代码以提供团队作为选项。 我将问题归结为以下示例案例:

我的示例中有两个类:一个表示业务对象(Foo),另一个表示此业务项(FooVO)的客户端版本(View Object),如下所示…

 public class Foo { public string Id {get; set;} public string BusinessInfo {get; set;} } public class FooVO { public string Id {get; set;} public static implicit operator FooVO( Foo foo ) { return new FooVO { Id = foo.Id }; } } 

我的问题是,当我有一个Foo对象列表,并希望使用我的隐式运算符将它们转换为FooVO对象列表。

 List foos = GetListOfBusinessFoos(); // Get business objects to convert 

我试过了

 List fooVOs = foos; // ERROR 

 List fooVOs = (List) foos; // ERROR 

乃至

 List fooVOs = foos.Select( x => x ); // ERROR 

我知道我可以在循环中执行此操作,但我希望能够直接(LINQ?)方式一次转换对象。 有任何想法吗?

先感谢您。

编辑修复了示例中的拼写错误

几乎每天都会问这样一个问题。 你不能这样做,因为这样做违反了类型安全:

 List g = new List(); List a = g; // Should this be legal? a.Add(new Tiger()); // Nope; we just added a tiger to a list of giraffes. 

在C#4.0中,您可以隐式地从IEnumerable转换为IEnumerable因为没有“添加”方法来搞砸了。 但是,如果元素类型的转换是用户定义的 ,那么你永远不能进行“协变”转换。 它必须是参考身份转换。

您需要创建第二个列表并一次复制一个列表。 或者使用像Select和ToList这样的LINQ辅助方法为您完成这项工作。

你想要的类型系统概念的名称是“协方差”; 一个协变关系就是你推理“长颈鹿是动物因此长颈鹿的序列是动物序列”的关系。 如果您对此主题感兴趣,那么您可以在此处阅读我们如何在C#4.0中添加协方差(和逆变):

http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/default.aspx

从底部开始。

您的示例不起作用的原因是您尝试将IEnumerable分配给List 。 以下应该有效。

  List fooVos = foos.Select(x => x).ToList(); 
 List d = new List(foos.Select(x => (FooVO)x)); 

适合我。

使用ConvertAll方法传递static implicit operator FooVO( Foo foo )作为参数

 List fooVOs = foos.ConvertAll(FooVO.FooVO);