0

我想按照以下代码将一个画笔实例的详细信息复制到一个新实例:

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

            // code to copy settings from b to b1

            return b1;
        }

我的困难是 Brush 是一个抽象类,所以我无法实例化它。我有许多从 Brush 继承的不同类,我可以将它们中的任何一个传递给这个方法。继承类都在 Brush 中使用相同的属性,因此复制它们不是问题。可以在调用源将返回值强制转换回继承类型。

4

3 回答 3

1

如果您的所有派生类都保证有一个具有特定签名的构造函数,例如没有任何参数,您可以根据其Type实例实例化相应的子类型:

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

如果不能保证,则需要在类中引入虚拟方法Brush来创建当前类的新实例。子类可以覆盖它以调用合适的构造函数。

更具体地说,您的Brush类可以具有以下方法:

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

在任何需要不同构造函数参数的派生类中,重写此方法并使用适当的参数值调用该Activator.Create(Type, object[])方法。

(这假定这CopyBrushBrush该类的一个方法。否则,使用该方法internalpublic该方法的可见性CreateBrushInstance。)

于 2012-08-25T21:12:08.930 回答
1

情况 1:您的所有Brush派生类都有一个公共默认构造函数,并且所有属性都有公共设置器。

在这种情况下,一个通用方法就足够了:

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

案例二:不满足以上一项或多项前提条件;即没有公共默认构造函数,或者至少一个属性不可公开设置。

您可以使用此模式:

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);
    }
}
于 2012-08-25T21:12:45.220 回答
-1

尝试克隆方法

http://msdn.microsoft.com/fr-fr/library/system.drawing.brush.clone%28v=vs.90%29.aspx

于 2012-08-25T21:06:29.733 回答