[英]How to implement the copy method of the decorator of a generic class?
Imagine you have a generic interface that defines a generic value and a copy constructor like this (replacing ICloneable): 想象一下,你有一个定义通用值的泛型接口和这样的复制构造函数(替换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();
}
This could be implemented by a boolean value holder like this: 这可以通过像这样的布尔值持有者来实现:
class BooleanHolder : ICopyable<Boolean, BooleanHolder> {
public BooleanHolder Copy() {
return new BooleanHolder(){ Value = Value };
}
}
Now comes the question: How would you define a decorator class that holds another ICopyable? 现在问题是:你如何定义一个装有另一个ICopyable的装饰器类? My not working idea was: 我不懂的想法是:
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 };
}
}
Note that I called Copy
to also have the value of type ICopyable<T,TU>
copied, this is on purpose to ensure deep copies. 请注意,我调用Copy
to也具有Copy
类型ICopyable<T,TU>
的值,这是为了确保深层复制。
So what do I have to change to make this structure work? 那么我需要改变什么来使这个结构工作?
You might just need to add a constraint. 您可能只需要添加约束。 You define that ICopyable<T, TU> where TU : ICopyable<T, TU>
but in your DecoratingHolder
, you never explicitly constraint TU
as such on DecoratingHolder
. 你定义了ICopyable<T, TU> where TU : ICopyable<T, TU>
但在你的DecoratingHolder
,你从来没有在DecoratingHolder
上明确地约束TU
。
More specifically, I think it's this part of the line: 更具体地说,我认为这就是这一部分:
class DecoratingHolder<T,TU> : ***ICopyable<ICopyable<T,TU>***
That's causing the issue. 这导致了这个问题。 You're defining a ICopyable<T,TU>
type, but TU
has not been constrained to be ICopyable<T, TU>
. 您正在定义ICopyable<T,TU>
类型,但TU
尚未被限制为ICopyable<T, TU>
。 (one might be able to infer that from the rest of the class declaration/inheritance, but the compiler doesn't) Once you add the constraint, then the compiler knows that Value
is a compatible ICopyable<T,TU>
type. (可能能够从类声明/继承的其余部分推断出 ,但编译器没有)一旦添加约束,编译器就知道 Value
是兼容的ICopyable<T,TU>
类型。
This compiles fine for me (had to fix some other minor things with the pseudocode you provided): 这对我编译很好(必须使用你提供的伪代码修复其他一些小的东西):
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 };
}
}
EDIT: In retrospect, do you even need that constraint on ICopyable
? 编辑:回想起来,你甚至需要在ICopyable
上有这个约束吗? Seems to not do much as you already generically define the outgoing type anyway. 似乎没有做太多,因为你已经一般地定义了传出类型。 Unless you have code elsewhere that depends on the fact that it returns ICopyable<T, TU>
for some reason (it would inherently anyway as it would return a strongly typed TU
or BooleanHolder
or DecoratingHolder
) then consider dumping it. 除非你在其他地方有代码,这取决于它由于某种原因返回ICopyable<T, TU>
这一事实(无论如何它会返回强类型的TU
或BooleanHolder
或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 };
}
}
EDIT: From your comment requiring a deep copy, keep the constraints then (you'll need them), and invoke Copy
on Value
(sorry, I must have missed that detail) 编辑:从你的评论需要深层复制,然后保持约束(你需要它们),并调用Copy
Value
(对不起,我一定错过了这个细节)
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() };
}
}
The Copy
methods for any given class should then make sure they perform a deep copy. 然后,任何给定类的Copy
方法应确保它们执行深层复制。 (I would suggest renaming Copy
to DeepCopy
if your framework needs them to be deep copy and you don't want implementations to do shallows accidentally) (如果您的框架需要深层复制并且您不希望实现意外地执行浅滩,我建议将Copy
重命名为DeepCopy
)
A cast worked for me: 演员为我工作:
public DecoratingHolder<T, TU> Copy()
{
return new DecoratingHolder<T, TU>() { Value = (ICopyable<T, TU>)Value.Copy() };
}
I guess in this context the compiler doesn't go as far as to establish that TU
and ICopyable<T, TU>
is the same thing. 我想在这种情况下,编译器没有尽可能地确定TU
和ICopyable<T, TU>
是一回事。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.