簡體   English   中英

在linq或lambda表達式中轉換匿名對象的類型

[英]Convert type of anonymous object in linq or lambda expression

我遇到以下情況,我有一個返回List<object ,因為該對象可以是2個不同的類型Class1Class2 ,但從不混合。 我將這個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();

編輯 :據我所知,已經有兩個使用強制轉換的答案,所以我將向您提出另一個解決方案。這並不意味着您必須實現它。

如果您知道將只有Class1Class2作為類型,並且每個類型在不同的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;

此時,您具有由Class1Class2對象形成的動態對象列表,但從未混合在一起。 因此,強制轉換和使用動態均應起作用。 您不會得到RuntimeBindingException異常,因為列表中有相同類型的對象,並且從列表中請求該項目中不存在的屬性時,也不會獲得RuntimeBindingException ,因為您知道要問什么(正如您在問題中所說的)。

您應該能夠執行以下操作:

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

注意 :如果您的列表中混有Class1Class2對象,則在請求不存在的字段時會出現運行時異常。

沒有其他注釋 :我在上面所做的注釋也可用於投射。 您將獲得System.InvalidCastException異常。

您不會有intellisense因為您的類型是在執行時而不是在編譯時由DLR評估的。 另外,您無需在代碼中進行其他強制轉換,裝箱或拆箱。

PS:C#4.0中提供了DLR

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM