繁体   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