在linq或lambda表达式

时间:2016-01-15 08:00:33

标签: c# linq lambda

我有以下情况,我有一个返回List<object的函数,因为该对象可以是2种不同类型Class1Class2,但从不混合。我在很多方面使用这个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布尔值定义,因此可以工作。

3 个答案:

答案 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>

如果您知道自己只有Class1Class2作为类型,并且每个类型都可以在不同的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;

此时,您有一个由Class1Class2个对象组成的动态对象列表,但从未混合过。因此,施放和使用动态都应该有效。由于您的列表中包含相同类型的对象,因此您无法获得强制转换异常,并且在请求该项目中不存在的属性时您也不会获得RuntimeBindingException列表,因为你知道要求什么(正如你在问题中所说)。

你应该可以这样做:

if (useFullProces)
{
    resultNames= result.Select(x=>x.ID).ToList();  
}
else
{
    resultNames = result.Select(x=>x.Name).ToList();
}

注意:如果您的列表与Class1Class2对象混合使用,那么在请求不符合字段的字段时,您会收到运行时异常存在。

不是另一个音符:注意我上面提到的也可用于演员。您将获得System.InvalidCastException例外。

您不会拥有intellisense,因为您的类型在执行时由DLR评估,而不是在编译时评估。此外,您不需要在代码中进行其他演员表,装箱或取消装箱。

PS:DLR可从C#4.0获得