[英]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.