继承扩展方法中的多个泛型

时间:2016-06-02 19:36:12

标签: c# generics extension-methods

目标:

在一个图书馆(DAL)中,我有一堆课程......其中一个被称为"产品"。在第二个库(BLL)中,我有一堆相应的类......包括它自己的"产品"类。类定义不一样。某些属性具有不同的名称(例如,ProductID与Id)。一个库中的类可能具有其他库中不存在的其他属性。有很多这样的类。我希望以最佳方式了解如何在两个类之间进行翻译。

是的,我知道AutoMapper存在。我试图学习如何使用泛型和扩展方法。

我知道对于每对类,需要实现四种方法:

  1. BLL.Product上的属性值应用于DAL.Product的方法。
    • 或者......并且最好是DAL.Product的扩展方法,它应用来自给定BLL.Product的值。
  2. 相同,但应用的值从DAL.ProductBLL.Product
  3. 实例化新DAL.Product然后应用给定BLL.Product的值的方法(使用上述方法)。
    • 或者......并且是首选的,BLL.Product的扩展方法,返回新的DAL.Product
  4. 相同,但将新BLL.Product实例化为DAL.Product的副本。
  5. 没有扩展方法,我有这个工作代码:

    public abstract class Adapter<DomainType, PortalType> {
       protected abstract DomainType ToDomainType (PortalType EntityToConvert);
       protected abstract PortalType ToPortalType (DomainType EntityToConvert);
       protected abstract void ApplyValuesTo (PortalType _That, ref DomainType _This);
       protected abstract void ApplyValuesTo (DomainType _That, ref PortalType _This);
    }
    
    public class ProductAdapter : Adapter<BLL.Product, DAL.Product> {
       protected override BLL.Product ToDomainType (DAL.Product EntityToConvert) {
          BLL.Product ConvertedEntity = new BLL.Product ();
          ApplyValuesTo (EntityToConvert, ref ConvertedEntity);
          return ConvertedEntity;
       }
    
       protected override DAL.Product ToPortalType (BLL.Product EntityToConvert) {
          DAL.Product ConvertedEntity = new DAL.Product ();
          ApplyValuesTo (EntityToConvert, ref ConvertedEntity);
          return ConvertedEntity;
       }
    
       protected override void ApplyValuesTo (DAL.Product _That, ref BLL.Product _This) {
          _This.Id = _That.ProductId;
          _This.Label = _That.Label;
          // yada yada yada
       }
    
       protected override void ApplyValuesTo (BLL.Product _That, ref DAL.Product _This) {
          _This.ProductId = _That.Id;
          _This.Label = _That.Label;
          // yada yada yada
       }
    }
    

    我已经意识到我的ApplyValuesTo方法将针对每对类具体,但我的ToDomainTypeToPortalType方法非常相似。

    protected override OneType ToOneType (AnotherType EntityToConvert) {
       OneType ConvertedEntity = new OneType (); // The only line that changes; different pairs of classes will be instantiating different types of objects.
       ApplyValuesTo (EntityToConvert, ref ConvertedEntity);
       return ConvertedEntity;
    }
    

    当然,有一种方法可以将其转移到基类,但是如何? (注意:我的所有类都有类似的构造函数,但我还没有决定它们是否是无参数构造函数。而且根据库,我的类可能没有共同的基础...责备EntityFramework for这一点。)

    对于我的ApplyValuesTo方法,我对传递ref参数非常不满意。我更喜欢扩展方法的语法。类似的东西:

    public static class ProductAdapter {
       public static void GetValuesFrom (this DAL.Product _This, BLL.Product _That) {
          _This.ProductId = _That.Id;
          _This.Label = _That.Label;
          // yada yada yada
       }
    }
    
    // Usage
    DALProductInstance.GetValuesFrom (BLLProductInstance);
    

    这很好,花花公子,但似乎这应该是使用泛型在抽象基类中定义的东西。

    所以这就是我想要的。这是我天真以为应该工作的。

    public abstract static class Adapter<DomainType, PortalType> {
       public abstract static void GetValuesFrom (this DomainType _This, PortalType _That);
       public abstract static void GetValuesFrom (this PortalType _This, DomainType _That);
    
       public static PortalType Adapt (this DomainType _This) {
          PortalType ConvertedEntity = new PortalType ();
          ConvertedEntity.GetValuesFrom (_This);
          return ConvertedEntity;
       }
    
       public static DomainType Adapt (this PortalType _This) {
          DomainType ConvertedEntity = new DomainType ();
          ConvertedEntity.GetValuesFrom (_This);
          return ConvertedEntity;
       }
    }
    
    public static ProductAdapter : Adapter<BLL.Product, DAL.Product> {
       public override static void GetValuesFrom (this BLL.Product _This, DAL.Product _That) {
          _This.ProductId = _That.Id;
          // yada yada yada
       }
    
       public override static void GetValuesFrom (this DAL.Product _This, BLL.Product _That) {
          _This.Id = _That.ProductId;
          // yada yada yada
       }
    }
    

    这有一些严重的编译问题。首先,你不能使用泛型的静态类。所以相反......

    public static abstract class Adapter {
       public static PortalType Adapt<PortalType, DomainType> (this DomainType _This) {}
    }
    

    但是......您无法在方法中定义多个泛型类型,而无需通过方法参数指定所有这些类型。 (This

    经过一些研究,找到像thisthis之类的东西,我得到的感觉是,我可以使用类似流畅的API更加接近。 (方法链?)但我还没弄明白如何做到这一点。

    让我天真的解决方案发挥作用的正确语法是什么?

0 个答案:

没有答案