[英]Convert type of anonymous object in linq or lambda expression
我遇到以下情况,我有一个返回List<object
,因为该对象可以是2个不同的类型Class1
或Class2
,但从不混合。 我将这个List用于很多事情,但是有时需要一个列出对象名称的List<string>
: List<string>
。
我知道如何在for循环中执行此操作,但是我想知道是否有一个很好的linq / lambda技巧。 由于它简化了代码。
// An extreme simplified version of my code
List<object> result = this.ProcesInput(input, useFullProces);
List<string> resultNames;
// The following ideas didn't work.
if (useFullProces)
{
resultNames = result.Select(x as Class2 => x.ID.toString()).ToList();
resultNames = result.Select(x => (Class2)x.ID.toString()).ToList();
}
else
{
resultNames = result.Select(x as Class1 => x.name).ToList();
}
我也知道这可以视为危险代码,但是在我的情况下,返回对象的类型由useFullProces
布尔值定义,因此可以正常工作。
我怀疑你只是想要:
List<string> names = useFullProcess
? result.Cast<Class2>().Select(x => x.ID.ToString()).ToList()
: result.Cast<Class1>().Select(x => x.Name).ToList();
您可以在Select
使用强制类型转换,但IMO尚不明确:
List<string> names = useFullProcess
? result.Select(x => ((Class2) x).ID.ToString()).ToList()
: result.Select(x => ((Class1) x).Name).ToList();
您需要投射正确的对象:
resultNames = result.Select(x => ((Class2)x).ID.toString()).ToList();
要么:
resultNames = result.Select(x => (x as Class2).ID.toString()).ToList();
编辑 :据我所知,已经有两个使用强制转换的答案,所以我将向您提出另一个解决方案。这并不意味着您必须实现它。
如果您知道将只有Class1
和Class2
作为类型,并且每个类型在不同的if-else branch
上都可用, if-else branch
可以利用DLR
(动态语言运行时)。
假设您有上面提到的2个classes
。
public class Class1
{
public string Name { get; set; }
}
public class Class2
{
public int ID { get; set; }
}
您说您知道每个分支上的类型。 因此,在if
分支上,假设您有一个由Class2
类型的对象形成的列表,在else
分支上,您具有了一个具有Class1
对象的列表。
List<dynamic> result = this.ProcesInput(input, useFullProces);
List<string> resultNames;
此时,您具有由Class1
或Class2
对象形成的动态对象列表,但从未混合在一起。 因此,强制转换和使用动态均应起作用。 您不会得到RuntimeBindingException
异常,因为列表中有相同类型的对象,并且从列表中请求该项目中不存在的属性时,也不会获得RuntimeBindingException
,因为您知道要问什么(正如您在问题中所说的)。
您应该能够执行以下操作:
if (useFullProces)
{
resultNames= result.Select(x=>x.ID).ToList();
}
else
{
resultNames = result.Select(x=>x.Name).ToList();
}
注意 :如果您的列表中混有Class1
和Class2
对象,则在请求不存在的字段时会出现运行时异常。
没有其他注释 :我在上面所做的注释也可用于投射。 您将获得System.InvalidCastException
异常。
您不会有intellisense
因为您的类型是在执行时而不是在编译时由DLR评估的。 另外,您无需在代码中进行其他强制转换,装箱或拆箱。
PS:C#4.0中提供了DLR
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.