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

时间:2013-01-30 09:10:05

标签: c# .net generics inheritance

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

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>的属性设置为details属性Result<T>类。

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

3 个答案:

答案 0 :(得分:2)

如果将父类型的对象创建为父类型(使用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,这从您的问题中难以辨别。

答案 1 :(得分:0)

ClientResult<T>课程中,您可以自定义从ClientResult转换为ClientResult<T>

public static explicit operator ClientReault<T>(ClientResult result)
{
       //do your conversion from one to the other here
}
然后你可以像这样编写ToClientResult

 //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-a关系时

答案 2 :(得分:0)

您应该明确地进行转换:

    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这样的工具