You just need to add a restriction. You define that ICopyable<T, TU> where TU : ICopyable<T, TU> , but in your DecoratingHolder , you never explicitly limit TU as such to the DecoratingHolder .
In particular, I think this part of the line:
class DecoratingHolder<T,TU> : ***ICopyable<ICopyable<T,TU>***
This is causing a problem. You define the type of ICopyable<T,TU> , but TU not limited to ICopyable<T, TU> . (one might conclude that from the rest of the class / inheritance declaration, but the compiler does not). When you add a constraint, the compiler knows that Value is a compatible type of ICopyable<T,TU> .
This compiles for me (it was necessary to fix some other minor things with the provided pseudocode):
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 a restriction on ICopyable ? It seems that you are not doing much, as you already generally define the outgoing type. If you do not have the code elsewhere, it depends on the fact that for some reason it returns ICopyable<T, TU> (it would essentially be one or the other, since it would return a strongly typed TU or BooleanHolder or DecoratingHolder ) , and then thought about dumping it.
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, save the restrictions (you'll need) and call Copy on Value (sorry, I must have missed this detail)
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 methods for any given class must be sure that they perform a deep copy. (I would suggest renaming Copy to DeepCopy if your infrastructure needs a deep copy of them and you donβt want the implementations to do small small things by accident)