2016-05-13 85 views
1

我有一组我无法触及的类对象。他们都有一个ID属性,我想以通用的方式访问其他功能。创建多对一的关系

为了简单起见,这里是我的问题的一个例子。

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

我不能够编辑这两种类别或他们是在图书馆。

我也有一个期望中的标识可以来自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; 
     } 
    } 
+1

你可以添加一个扩展方法到类Example1,Example2吗? –

回答

0

下面是我们最终使用的解决方案和原因。

我们正在使用的继承结构,它采用以下两个基本类别:

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>参数的函数) 。显然这个解决方案变得不太好,因为更多的类型被添加到这个混合。

2

可能采用的解决方案扩展方法,您可以添加一个静态方法使用反射:

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

然后,你可以与任何对象调用它来获得id属性值。

+0

这工作,但仍需要一些包装。我需要从我的函数外部调用这些函数,然后将结果传入。这是一个很好的解决方案,但是您是否知道一种限制函数的方法,只接受'Example1'或'Example2',而不是String?还是需要包装?我一直没有想到在函数前面用'examples.Select((ex)=> ex.GetId())'这样的方法。 –

+0

我不认为我站在你面前quesion。扩展方法的意思是,比现在当你创建一个对象时,它具有该功能。即:Example1 ex = new Example()。你有ex.GetId()。 –

+0

这里的目标似乎是将事物置于相同类型下,或允许其他通用实现。我不确定我通过添加扩展方法获得了什么,除非我可以要求它们以某种方式存在。通过调用GetId()与简单调用对象ID属性,我可以获得什么? –

0

+0

我对反射或动态类解决方案的关注是,都需要基于运行时的错误检查。如果可能的话,在编译时得到错误将是理想的。 –