简体   繁体   English

级联多个接口的扩展方法?

[英]Cascading extension methods for multiple interfaces?

I have multiple interfaces that my objects can implement. 我的对象可以实现多个接口。 I am wondering if there is a way to "cascade" one extension method into another while using the same method name. 我想知道是否有一种方法可以在使用相同方法名称的同时将一个扩展方法“级联”为另一种扩展方法。 I may be looking at this all wrong, but here is an example: 我可能看错了一切,但这是一个示例:

public interface IBaseDto
{
     int Id {get;set;}
     string CreatedByFullName {get;set;}
}

public interface IDocumentDto
{
     List<ContactDto> Subscriptions {get;set;}
}

public class ContactDto: IBaseDto
{
     public int Id {get;set;}
     public string CreatedByFullName {get;set;}
     public string FirstName {get; set}
     public string LastName {get;set;}
}

public class MeetingDto: IDocumentDto
{
     public int Id {get;set;}
     public string CreatedByFullName {get;set;}
     public List<ContactDto> Subscriptions {get;set;}
}

So, let's say I want to convert the DTOs into entities using an extension method. 因此,假设我要使用扩展方法将DTO转换为实体。 An example would be MeetingDto.ToEntity() ; 一个示例是MeetingDto.ToEntity() ;

I am trying to think if I can write part of the extension method for an IBaseDto , another for the IDocumentDto and then for each concrete implementations for just their own properties. 我试图考虑是否可以为IBaseDto编写扩展方法的IBaseDto ,为IDocumentDto编写扩展方法的IBaseDto ,然后为每种具体实现为其自身的属性编写扩展方法。 When I call MeetingDto.ToEntity() it would first hit the meeting extension method and call the IDocumentDto version, fill in what it needed, and then the IDocumentDto would call the IBaseDto . 当我调用MeetingDto.ToEntity() ,它将首先使用会议扩展方法并调用IDocumentDto版本,填写所需的内容,然后IDocumentDto将调用IBaseDto I hope this makes sense. 我希望这是有道理的。

UPDATE: 更新:

I came up with this and it works pretty well: 我想到了这一点,并且效果很好:

public static TBaseDto ToEntity<TBridgeDto>(this TBaseDto dto) where TBaseDto: IBaseDto
        {
...            
return dto;
        }


        public static TDocumentDto ToEntity<TDocumentDto>(this TDocumentDto dto, IDocumentDto currentDto) where TDocumentDto : IDocumentDto
        {
...            
return dto.ToEntity();
        }

        public static MeetingDto ToEntity(this RfiDto dto)
        {
...            
return dto.ToEntity(dto)

        }

Yes you can..... just cast to the interface you want... 是的,您可以.....只需投射到所需的界面...

eg 例如

 interface I1
    {
        int Id { get; set; }
    }

    public interface I2
    {
        string Name { get; set; }
    }

    public class Blah : I1, I2
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    static class ExtendIt
    {
        public static void ToEntity(this I1 x)
        {
            x.Id = 1;
        }

        public static void ToEntity(this I2 x)
        {
            x.Name = "hello";
        }

        public static void ToEntity(this Blah x)
        {
            (x as I1).ToEntity();
            (x as I2).ToEntity();
        }


    }

Like this? 像这样?

public static class Helper
{
    public static void ToEntity(this MeetingDto source)
    {
        Console.WriteLine ("MeetingDto.ToEntity");
        //Do Stuff
        (source as IDocumentDto).ToEntity();
    }

    public static void ToEntity(this ContactDto source)
    {
        Console.WriteLine ("ContactDto.ToEntity");
        //Do Stuff
        (source as IBaseDto).ToEntity();
    }

    public static void ToEntity(this IDocumentDto source)
    {
        Console.WriteLine ("IDocumentDto.ToEntity");
        //Do Stuff
        foreach (var element in source.Subscriptions)
        {
            element.ToEntity();
        }
    }

    public static void ToEntity(this IBaseDto source)
    {
        Console.WriteLine ("IBaseDto.ToEntity");
        //Do Stuff        
    }
}

Extension methods are static, and as such they cannot be overridden using inheritance. 扩展方法是静态的,因此不能使用继承覆盖它们。

If you want it to apply to every element, why not just have both interfaces implement a 3rd interface with your ToEntity method? 如果希望将其应用于每个元素,为什么不让两个接口都使用ToEntity方法实现第3个接口?

If you can't modify those classes, then consider something akin to the IConverer interface. 如果您不能修改这些类,请考虑类似于IConverer接口的内容。 Have an interface with a method that takes...something, and returns an entity. 具有一个接口,该接口的方法可以接收某物,然后返回一个实体。 (It could be generic.) This way you are separating out the code to convert each of those types to entities, much as you would with extension methods. (这可能是通用的。)通过这种方式,您可以分离出将每种类型转换为实体的代码,就像使用扩展方法一样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM