我有以下情况,我有一个返回List<object
的函数,因为该对象可以是2种不同类型Class1
或Class2
,但从不混合。我在很多方面使用这个List,但在某些时候我需要一个包含对象名称的列表: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
布尔值定义,因此可以工作。
答案 0 :(得分:3)
我怀疑你只是想要:
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();
答案 1 :(得分:2)
您需要投射正确的对象:
resultNames = result.Select(x => ((Class2)x).ID.toString()).ToList();
或:
resultNames = result.Select(x => (x as Class2).ID.toString()).ToList();
答案 2 :(得分:2)
编辑:我看到已经有两个使用演员的答案,所以我打算给你另一个解决方案。这并不代表你必须实现它。< / p>
如果您知道自己只有Class1
和Class2
作为类型,并且每个类型都可以在不同的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
列表,因为你知道要求什么(正如你在问题中所说)。
你应该可以这样做:
if (useFullProces)
{
resultNames= result.Select(x=>x.ID).ToList();
}
else
{
resultNames = result.Select(x=>x.Name).ToList();
}
注意:如果您的列表与Class1
和Class2
对象混合使用,那么在请求不符合字段的字段时,您会收到运行时异常存在。
不是另一个音符:注意我上面提到的也可用于演员。您将获得System.InvalidCastException
例外。
您不会拥有intellisense
,因为您的类型在执行时由DLR评估,而不是在编译时评估。此外,您不需要在代码中进行其他演员表,装箱或取消装箱。
PS:DLR
可从C#4.0获得