创建多对一类关系

时间:2016-05-13 15:39:22

标签: c#

我有一组我无法触及的类对象。所有这些都有一个ID属性,我想以通用方式访问其他函数。

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

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

我无法编辑这两个类或它们所在的库中的任何一个。

我还有一个函数,它需要一个可以来自Example1Example2的ID。为了解决这个问题,我提出了许多解决方案,但我很好奇解决这个问题的正确方法是什么。

我可以:

  1. 使用动态类访问各种类ID
  2. 使用反射从任何给定类型中提取ID参数。
  3. 通过创建一个新类来使用奇数继承,以便在我的函数中Example1ViewModel : Example1, IIdentifiableObject然后期望IIdentifiableObject并在Example1ViewModel中实现一个复制构造函数来处理收集数据
  4. 编写一个单独的过滤函数,可以从任一类中提取相关部分并提供结果。
  5. 这些解决方案对我来说都不是特别好。我应该如何在代码中处理这样的多对一关系?是否有C#提供的工具来处理这个问题?

3 个答案:

答案 0 :(得分:2)

使用类的扩展方法

的可能解决方案
    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 :(得分:0)

您可以使用反射添加静态方法:

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

然后,您可以使用任何对象调用它来获取id属性值。

答案 2 :(得分:0)

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

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

FooExample
BarExample

并将它们包含在以下

IExample
FooExampleModel : IExample
BarExampleModel : IExample

FooExampleModelBarExampleModel都有构造函数接受它们正在包装的类。

这一点的重要性在于它允许我们创建接受IExample实例的方法,而无需事先操作数据。此外,与使用动态类型或反射不同,此解决方案为我们提供了编译时错误检查。

不幸的是,使用扩展方法不起作用。虽然它允许我们在两个不同的对象类型上调用相同的方法,就像我们想要的那样,它不允许将这些对象作为Generic类型传递给单独的函数。

所有这一切的结果是现在可以:

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>参数的函数)。显然,随着更多类型被添加到这种混合中,这个解决方案变得不那么好了。