简体   繁体   English

如何编写通用方法来复制均从同一抽象基类继承的类的实例?

[英]How do I write a general method to copy instances of classes that all inherit from the same abstract base class?

I want to copy the details of one instance of a brush to a new instance as per the code below: 我想按照以下代码将一个画笔实例的详细信息复制到一个新实例:

private static Brush CopyBrush(Brush b)
        {
            Brush b1 = new Brush();

            // code to copy settings from b to b1

            return b1;
        }

My difficulty is that Brush is an abstract class so I cannot instantiate it. 我的困难是Brush是一个抽象类,因此我无法实例化它。 I have a number of different classes inheriting from Brush and I could pass anyone of them to this method. 我有许多不同的类继承自Brush,可以将其中的任何一个都传递给此方法。 The inherriting classes all use the same properties in Brush so copying them is not a problem. 继承类都在Brush中使用相同的属性,因此复制它们不是问题。 The return can be cast back to the inheriting type at the call source. 可以在调用源将返回值强制转换回继承类型。

If all of your derived classes are guaranteed to have a constructor with a certain signature, eg without any arguments, you can instantiate the respective subtype based on its Type instance: 如果保证所有派生类都具有带有特定签名的构造函数(例如,不带任何参数),则可以基于其子Type实例实例化各自的子Type

Brush b1 = (Brush)Activator.CreateInstance(b.GetType());

If that cannot be guaranteed, you'll need to introduce a virtual method in your Brush class to create a new instance of the current class. 如果不能保证这一点,则需要在Brush类中引入虚拟方法来创建当前类的新实例。 Subclasses can override it to invoke a suitable constructor. 子类可以重写它以调用合适的构造函数。

More concretely, your Brush class could have the following method: 更具体地说,您的Brush类可以具有以下方法:

protected virtual Brush CreateBrushInstance()
{
    return (Brush)Activator.CreateInstance(GetType());
}

In any derived class that requires different constructor arguments, override this method and call the Activator.Create(Type, object[]) method with the appropriate argument values. 在需要不同构造函数参数的任何派生类中,重写此方法并使用适当的参数值调用Activator.Create(Type, object[])方法

(This assumes that CopyBrush is a method of the Brush class. Otherwise, use internal or public visibility for the CreateBrushInstance method.) (这假定CopyBrushBrush类的方法。否则,对CreateBrushInstance方法使用internalpublic可见性。)

Case 1: All your Brush -derived classes have a public default constructor, and all properties have public setters. 情况1:您所有从Brush派生的类都有一个公共的默认构造函数,而所有属性都有一个公共的setter。

In this case, one generic method should suffice: 在这种情况下,一个通用方法就足够了:

static TBrush Copy<TBrush>(this TBrush brush) where TBrush : Brush, new()
{
    return new TBrush() // <- possible due to the `new()` constraint ^^^
           {
               TypeOfHair = brush.TypeOfHair,
               NumberOfHairs = brush.NumberOfHairs,
               …
           };
}

Case 2: One or more of the above preconditions are not met; 情况2:不满足上述一个或多个前提条件; ie there is no public default constructor, or at least one property is not publicly settable. 也就是说,没有公共默认构造函数,或者至少一个属性是不可公开设置的。

You can use this pattern: 您可以使用以下模式:

abstract class Brush
{
    protected abstract Brush PrepareCopy();
    // replacement for public default ctor; prepares a copy of the derived brush
    // where all private members have been copied into the new, returned instance.

    public Brush Copy()
    {
        // (1) let the derived class prepare a copy of itself with all inaccessible
        //     members copied:
        Brush copy = PrepareCopy();

        // (2) let's copy the remaining publicly settable properties:
        copy.TypeOfHair = this.TypeOfHair;
        copy.NumberOfHairs = this.NumberOfHairs;

        return copy;
    } 
}

sealed class FooBrush : Brush
{
    public FooBrush(int somethingPrivate)
    {
        this.somethingPrivate = somethingPrivate;
        // might initialise other members here…
    }

    private readonly int somethingPrivate;

    protected override Brush PrepareCopy()
    {
        return new FooBrush(somethingPrivate);
    }
}

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

相关问题 如何从抽象基类多重继承? - How to mulitiply inherit from abstract base classes? Selenium C#如何从另一个类调用方法,两个类都从基类继承 - Selenium C# How do I call a method from another class both classes inherit from a base class Ninject:从相同抽象类继承的GetAll实例 - Ninject: GetAll instances that inherit from the same abstract class Microsoft如何使所有.NET类隐式继承自Object类? 我可以做同样的事情吗? - How does Microsoft make all .NET classes implicitly inherit from the Object class? Can I do the same kind of thing? 当所有子类都具有相同的基类(包括新类)时,如何继承多个子类? - How to inherit multiple partial classes when all have the same base class (including the new class)? 如何使用抽象基类继承内部类? - How can I inherit an inner class using an abstract base class? 如何从抽象的 UserControl 继承? - How do I inherit from an abstract UserControl? 如果部分类继承自某个类,那么具有相同名称的所有其他部分类也应该继承相同的基类? - If a partial class inherits from a class then all other partial classes with the same name should also inherit the same base class? 如何从用C#编写的抽象基类继承 - How to inherit from an abstract base class written in C# 如何从调用基本构造函数的类继承? - How do I inherit from class that calls base constructor?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM