将非泛型父类转换为泛型子类

本文关键字:泛型 子类 转换 父类 | 更新日期: 2023-09-27 17:56:49

有一个继承自非泛型类的泛型类,如下所示的结构:

public class Result
{
     public string ErrorCode { get; set;}
     public string ErrorMessage { get; set;}
     public boo Success { get; set;}
     //Lots more properties
     public ClientResult ToClientResult()
     {
         //some pretty involved calculations of error coded and status
     }
 }
 public class Result<T> : Result
 {
     public T details {get; set;}
     public ClientResult<T> ToClientResult<T>()
     {
        //Need to call the parent class implementation and convert result to  generic ver  
     }
 }

我的问题是我如何调用父ToClientResult()并将结果转换为 ClientResult<T> 的通用版本,然后我需要将ClientResult<T>的属性设置为 Result<T> 类的 details 属性。

确定我在这里错过了一个简单的解决方案,我真的不想复制父类逻辑,因为它非常复杂。

将非泛型父类转换为泛型子类

如果父

类型的对象被创建为父类型(使用 new ClientResult()),则不能将父类型的对象强制转换为子类型。它只是不是那样工作的。

你可以做的是将复杂的代码分解到另一种方法中,你用它来在Result类和Result<T>类中完成繁重的工作:

public class Result
{
    public string ErrorCode { get; set;}
    public string ErrorMessage { get; set;}
    public boo Success { get; set;}
    //Lots more properties
     public ClientResult ToClientResult()
     {
         var clientResult = new ClientResult();
         SetupClientResult(clientResult);
         return clientResult;
     }
     protected void SetupClientResult(ClientResult clientResult) 
     {    
         //some pretty involved calculations of error coded and status           
     }
}
public class Result<T> : Result
{
     public T details {get; set;}
     // This now shadows the original ToClientResult method. The trap here is that if
     // you are treating your Result<T> instance as a Result, this method will not be 
     // called, and the return type will be ClientResult and not ClientResult<T>.
     // See: http://stackoverflow.com/questions/392721/difference-between-shadowing-and-overriding-in-c?lq=1
     public ClientResult<T> ToClientResult()
     {
         var clientResult = new ClientResult<T>();
         SetupClientResult(clientResult);
         clientResult.SomeProperty = details;
         return clientResult;
     }
}

这都是假设ClientResult<T>来自ClientResult,这从你的问题中有点难以分辨。

ClientResult<T>类中,您可以进行从ClientResult到ClientResult<T>的自定义转换

public static explicit operator ClientReault<T>(ClientResult result)
{
       //do your conversion from one to the other here
}

然后你可以像这样写到客户端结果

 //Generic argument remove from method declaration
 //because it was shadowing the type argument
 public ClientResult<T> ToClientResult()
 {
    var clientResult = ((Result)this).ToClientResult()
    var genericResult = (ClientResult<T>)clientResult;
    //do what you need to do with the generically typed object
    //...
    return genericResult
 }

也就是说,当继承链中存在缺陷时,通常会出现这种情况。 例如,当基类和派生类之间没有 is 关系时

您应该明确执行转换:

    public class ClientResult
    {
        public int a {get;set;}
    }
    public class ClientResult<T> : ClientResult
    {
        public ClientResult(ClientResult cr)
        {
            this.a = cr.a;
        }
    }
    public class Result<T> : Result
    {
        public T details { get; set; }
        public ClientResult<T> ToClientResult<T>()
        {
            var cr = base.ToClientResult();
            return new ClientResult<T>(cr);  
        }
    }

如果你有很多类似于ClientResult的类,你可以使用像AutoMapper这样的工具