简体   繁体   English

在基本抽象类中使用派生类型

[英]Use derived type in base abstract class

Ok, I have a number of different classes deriving from a base class. 好吧,我有一些从基类派生的不同类。 This base class is an abstract containing commom methods. 此基类是包含commom方法的抽象。

One of the methods is a Copy method, wich should be present in all derived classes, so, I've put it in the base class. 其中一个方法是Copy方法,它应该出现在所有派生类中,所以,我把它放在基类中。 BUT, I want it to return the derived type not the base nor object. 但是,我希望它返回derived type而不是基础或对象。

The solution I got for that, is using a type paramter: 我得到的解决方案是使用类型参数:

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
    }
}

So, the main purpose here is to 所以,这里的主要目的是

Remove the type parameter in the base class and still make the method return the corresponding derived type. 删除基类中的type参数,仍然使该方法返回相应的派生类型。


One workaround. 一个解决方法。

The best thing I could do so far is one of the comments below, but it still uses a generic parameter 到目前为止我能做的最好的事情是以下评论之一,但它仍然使用通用参数

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
    }
}

You can't really. 你不能真的。 The base class can't possibly know all the future implementations. 基类不可能知道所有未来的实现。 You'll have to resort to a generic abstract class (like you did) type or a generic Copy method. 您将不得不求助于通用抽象类(就像您所做的)类型或通用的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
    }
}

Or, if you want to generalize the type check in your base class: 或者,如果要在基类中概括类型检查:

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;
    }
}

Note that the second method puts alot of trust into the implementation of the derived class as it'll blindly cast the return value of the abstracted method. 请注意,第二种方法将大量信任放入派生类的实现中,因为它将盲目地转换抽象方法的返回值。 The compiler will let you return another type, implementing CopyableClass, in a derived type but it will be a runtime error. 编译器将允许您在派生类型中返回另一个类型,实现CopyableClass,但它将是运行时错误。 This is not a problem if you have the absolute control over all of the derived implementations (ie your abstract class also have an internal constructor). 如果您对所有派生实现具有绝对控制权(即您的抽象类也具有内部构造函数),则这不是问题。

You actually want to implement copy in the base class and have it return T . 您实际上想要在基类中实现副本并让它返回T This will make is so you call it with a type argument and it returns that type. 这将使您使用类型参数调用它并返回该类型。

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

To call it you do; 打电话给你做;

DerivedClass d = Copy<DerivedClass>();

Your code to actually do the copy might be a bit more work to make generic but it's worth the effort given you will have a single implementation of Copy() that works for any derived type. 实际执行复制的代码可能需要更多的工作来制作泛型,但是值得付出努力,因为您将拥有适用于任何派生类型的Copy()的单个实现。 I don't know what logic belongs in the method so I've just stubbed things out. 我不知道该方法中有什么逻辑,所以我只是把事情搞砸了。 Also, I'd recommend checking out generics in general. 另外,我建议一般检查泛型。 They're often the best option for things like this. 对于像这样的事情,它们通常是最好的选择。 If your implementations need to be unique to the base class' keep the same method definition but make it abstract and then override it in the base classes. 如果你的实现需要对基类是唯一的'保持相同的方法定义但是使它成为抽象,然后在基类中重写它。

This will allow you to case this base class to the derived type and return it. 这将允许您将此基类置于派生类型并返回它。

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

This solution involves a middle class but I think its more inline with what the you are looking for. 这个解决方案涉及中产阶级,但我认为它更符合您的需求。 At least you get the possible benefit of isolating your copy code 至少你可以获得隔离复制代码的好处

    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>
    {
    }

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

相关问题 无法使用类型参数将派生类型强制转换为基类抽象类 - Can't cast derived type to base abstract class with type parameter 无法强制将抽象类的基础构造函数用于派生类 - Can't enforce the use of base constructor of an abstract class into derived class 在抽象基类中使用具体实现的类型 - Use type of concrete implementation in abstract base class 为什么派生类不能使用扩展该接口的类型覆盖基类的接口类型抽象属性? - Why can't a derived class override base class' interface type abstract property with a type that extends that interface? 使用派生类类型作为基类泛型操作的参数 - Use derived class type as parameter of generic action of base class 将方法上的泛型类型约束为从抽象泛型基类的任何变体形式派生的任何类 - Constrain generic type on a method to be any class that is derived from any variant form of an abstract generic base class 可以从基抽象类上的静态方法返回派生的泛型类型吗? - Can a derived generic type be returned from a static method on the base abstract class? 派生类型的通用基类 - Derived type of generic base class 可以在派生类中覆盖抽象类,而无需在基类中实现 - Can abstract class be override in derived class without implementing in base class 将类属性反序列化为派生类,而不是基础抽象类 - Deserialize class properties to derived class instead of base abstract class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM