簡體   English   中英

建立多對一關系

[英]Creating a Many to One Class Relationship

我有一組無法觸摸的類對象。 它們都有一個ID屬性,我想以其他通用方式在其他函數中訪問。

為簡單起見,這是我的問題的一個示例。

class Example1 {
   int ID { get; set;}
}
class Example2 {
   int ID { get; set; }
}

我無法編輯這兩個類或它們所在的庫。

我也有一個期望ID可以來自Example1Example2的函數。 為了解決這個問題,我提出了許多解決方案,但我想知道解決這個問題的正確方法是什么。

我可以:

  1. 使用動態類訪問各種類ID。
  2. 使用反射從任何給定類型中提取ID參數。
  3. 通過創建一個新類使用奇數繼承,以便Example1ViewModel : Example1, IIdentifiableObject ,然后在我的函數中期望IIdentifiableObject ,並在Example1ViewModel實現一個復制構造函數來處理數據收集
  4. 編寫一個單獨的過濾器函數,該函數可以從任一類中提取相關部分並提供結果。

這些解決方案對我來說似乎都不是特別好。 我應該如何在代碼中處理這樣的多對一關系,並且C#提供了一些工具來處理此問題?

使用擴展方法的類的可能解決方案

    public static class MyExtensions
    {
        public static int GetId(this Example1 ex)
        {
            return ex.Id;
        }

        public static int GetId(this Example2 ex)
        {
            return ex.Id;
        }
    }   

您可以使用反射添加靜態方法:

public static int GetId(object obj)
    {
        Type type = obj.GetType();
        return Convert.ToInt32(type.GetProperty("ID").GetValue(obj, null));
    }

然后,您可以使用任何對象調用它以獲取id屬性值。

這是我們最終使用的解決方案以及原因。

我們使用的繼承結構采用以下兩個基類:

FooExample
BarExample

並將它們包裝在下面

IExample
FooExampleModel : IExample
BarExampleModel : IExample

FooExampleModelBarExampleModel都有構造函數,它們接受要包裝的類。

這樣做的重要性在於,它允許我們創建接受IExample實例的方法,而不必事先處理數據。 此外,與使用動態類型或反射不同,此解決方案為我們提供了編譯時錯誤檢查。

不幸的是,使用擴展方法不起作用。 盡管它允許我們像我們希望的那樣在兩個不同的對象類型上調用相同的方法,但不允許將這些對象作為泛型類型傳遞給單獨的函數。

所有這些的結果是現在這是可能的:

var foos = new List<FooExample>(); //Pretend there is data here
var bars = new List<BarExample>();
var examples = foos.Select((foo) => (IExample)new FooExampleModel(foo))
                   .Concat(bars.Select((bar) => (IExample)new BarExampleModel(bar)))
                   .ToList(); // Force evaluation before function call
DoSomethingOnIExamples(examples);

除了稍微粗略的LINQ查詢,這似乎是完成此操作的最佳方法( DoSomethingOnIExamples(...)是接受IEnumerable<IExample>參數的函數)。 顯然,隨着更多類型添加到此混合中,此解決方案變得不太好用。

暫無
暫無

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

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