4

想象一下,你有一个通用接口,它定义了一个通用值和一个像这样的复制构造函数(替换 ICloneable):

// T: type of value to hold, TU: type of the class itself
interface ICopyable<T,TU> where TU: ICopyable<T,TU> {
    T Value { get; set; }
    TU Copy();
}

这可以通过像这样的布尔值持有者来实现:

class BooleanHolder : ICopyable<Boolean, BooleanHolder> {
    public BooleanHolder Copy() { 
        return new BooleanHolder(){ Value = Value }; 
    }
}

现在问题来了:你将如何定义一个包含另一个 ICopyable 的装饰器类?我不工作的想法是:

class DecoratingHolder<T,TU> : ICopyable<ICopyable<T,TU>, DecoratingHolder<T,TU>> {
    public DecoratingHolder<T,TU> Copy {
        // won't compile as Value is of type T and not of type ICopyable<T,TU> 
        // as I expected - why is that?
        return new DecoratingHolder<T,TU>(){ Value = Value.Copy };
    }
}

请注意,我Copy还要求复制类型的值ICopyable<T,TU>,这是为了确保深拷贝。

那么我必须改变什么才能使这个结构起作用呢?

4

2 回答 2

3

您可能只需要添加一个约束。您定义了它,ICopyable<T, TU> where TU : ICopyable<T, TU>但在您的 中,DecoratingHolder您永远不会明确约束TU.DecoratingHolder

更具体地说,我认为这是该行的这一部分:

class DecoratingHolder<T,TU> : ***ICopyable<ICopyable<T,TU>***

这就是问题的根源。您正在定义一个ICopyable<T,TU>类型,但TU并没有被限制为ICopyable<T, TU>. (也许可以从类声明/继承的其余部分推断出这一点,但编译器不会)一旦添加了约束,编译器就会知道Value是一个兼容的ICopyable<T,TU>类型。

这对我来说编译得很好(必须用您提供的伪代码修复一些其他小问题):

class DecoratingHolder<T,TU> : ICopyable<ICopyable<T,TU>, DecoratingHolder<T,TU>> 
    where TU : ICopyable<T,TU>
{
    public ICopyable<T,TU> Value { get; set; }

    public DecoratingHolder<T,TU> Copy() {
        return new DecoratingHolder<T, TU>(){ Value = Value };
    }
}

编辑:回想起来,你甚至需要那个约束ICopyable吗?似乎没有做太多,因为无论如何您已经普遍定义了传出类型。除非您在其他地方有代码取决于它ICopyable<T, TU>出于某种原因返回的事实(无论如何它都会固有地返回一个强类型的TUor BooleanHolderor DecoratingHolder),然后考虑转储它。

interface ICopyable<T,TU>
{
    T Value { get; set; }
    TU Copy();
}

class BooleanHolder : ICopyable<Boolean, BooleanHolder> 
{
    public bool Value { get; set; }
    public BooleanHolder Copy() { 
        return new BooleanHolder(){ Value = Value }; 
    }
}

class DecoratingHolder<T,TU> : ICopyable<ICopyable<T,TU>, DecoratingHolder<T,TU>> 
{
    public ICopyable<T,TU> Value { get; set; }

    public DecoratingHolder<T,TU> Copy() {
        return new DecoratingHolder<T, TU>(){ Value = Value };
    }
}

编辑:从您需要深拷贝的评论中,保留约束(您将需要它们),然后调用CopyValue对不起,我一定错过了那个细节)

class DecoratingHolder<T,TU> : ICopyable<ICopyable<T,TU>, DecoratingHolder<T,TU>> 
    where TU : ICopyable<T,TU>
{
    public ICopyable<T,TU> Value { get; set; }

    public DecoratingHolder<T,TU> Copy() {
        return new DecoratingHolder<T, TU>(){ Value = Value.Copy() };
    }
}

然后Copy,任何给定类的方法都应确保它们执行深层复制。(如果您的框架需要它们是深拷贝并且您不希望实现意外地做浅层,我建议重命名Copy为)DeepCopy

于 2012-11-24T14:12:40.950 回答
0

一个演员为我工作:

    public DecoratingHolder<T, TU> Copy()
    {
        return new DecoratingHolder<T, TU>() { Value = (ICopyable<T, TU>)Value.Copy() };
    }

我想在这种情况下,编译器并没有去建立这一点,TU而且ICopyable<T, TU>是一回事。

于 2012-11-24T14:12:47.767 回答