2013-07-02 86 views
5

好吧,我有许多不同的派生于基类的类。 该基类是一个包含通用方法的抽象。在基本抽象类中使用派生类型

其中一种方法是Copy方法,它应该出现在所有的派生类中,所以我把它放在基类中。 但是,我希望它返回derived type不是基地也不是对象。

我得到了该解决方案,使用类型放慢参数:

abstract class CopyableClass<T> 
{ 
    public abstract T Copy(); 
} 

class DerivedClass : CopyableClass<DerivedClass> 
{ 
    public override DerivedClass Copy() 
    { 
     //do what is needed for copy and return a new DerivedClass 
    } 
} 

因此,主要目的这里是

在基类中删除类型参数,仍然使方法返回相应的派生类型。


一个解决办法。

我能做迄今为止最好的事情是下面的意见之一,但它仍然采用了通用的参数

abstract class BaseClass 
{ 
    //base methods not related to deriving type 
} 

interface ICopyable<T> 
{ 
    T Copy(); 
} 

class DerivedClass : BaseClass, ICopyable<DerivedClass> 
{ 
    public DerivedClass Copy() 
    { 
     //do what is needed for copy and return a new DerivedClass 
    } 
} 
+0

那么你的问题是什么? – evanmcdonnal

+0

可能会更好地实现这个通用接口? –

+0

如何删除基类中的类型参数并仍然使该方法返回相应的派生类型。 –

回答

4

你真的不能。基类不可能知道所有未来的实现。你将不得不求助于一个通用的抽象类(像你一样)或者一个通用的方法Copy

public abstract class CopyableClass 
{ 
    public abstract T Copy<T>() where T : CopyableClass; 
} 

public class DerivedClass : CopyableClass 
{ 
    public override T Copy<T>() 
    { 
     if(typeof(T) != typeof(DerivedClass)) 
      throw new ArgumentException(); 

     // return your copy 
    } 
} 

或者,如果你想概括类型检查中的基础类:

public abstract class CopyableClass 
{ 
    public T Copy<T>() where T : CopyableClass 
    { 
     if(GetType() != typeof(T)) 
      throw new ArgumentException(); 

     return (T) Copy(); 
    } 

    protected abstract CopyableClass Copy(); 
} 

public class DerivedClass : CopyableClass 
{ 
    protected override CopyableClass Copy() 
    { 
     return // Your copy; 
    } 
} 

注意,第二个方法把信任的很多到派生类的实现,因为它会盲目施放抽象方法的返回值。编译器会让你返回另一个类型,在派生类型中实现CopyableClass,但它将是一个运行时错误。如果你对所有的派生实现有绝对的控制权(即你的抽象类也有一个内部构造函数),这不是问题。

0

你实际上想要在基类中实现拷贝并让它返回T。这将使你可以用一个类型参数来调用它并返回该类型。

public static T Copy<T>() where T : CopyableClass 
{ 
    T retVal = new T(); 
    // do whatever copying is required 
    return retVal; 
} 

给你打电话吧;

DerivedClass d = Copy<DerivedClass>(); 

您的代码进行实际的副本可能是更多的工作,以使通用的,但它是值得给你会有一个实施Copy(),对于任何派生类型工作的努力。我不知道该方法属于什么逻辑,所以我只是把事情弄糟了。另外,我建议一般检查泛型。他们通常是这样的事情的最佳选择。如果您的实现需要对基类是唯一的,请保留相同的方法定义,但将其抽象化,然后在基类中重写它。

0

这将允许您将此基类映射到派生类型并返回它。

public abstract class BaseClass<TDerived> : where TDerived: BaseClass<TDerived> 
{ 
    public TDerived DoSomethingCommon(string param) 
    { 
     var derivedType = (TElement)this; 
     //do something. 
     return derivedType; 
    } 
} 
0

该解决方案涉及一个中产阶级,但我认为它更符合你在找什么。至少你得到隔离你的复制代码的可能好处

public abstract class BaseClass 
    { 
    } 

    public abstract class CopyableClass<T> : BaseClass 
     where T: BaseClass, new() 
    { 
     public T Copy() 
     { 
      var copy = new T(); // Creating a new instance as proof of concept 

      return copy; 
     } 
    } 

    public class DerivedClass : CopyableClass<DerivedClass> 
    { 
    } 
相关问题