问题
I have the following covariant interface:
public interface IHierarchical<out T> where T : IHierarchical<T> {
T Parent { get; }
IEnumerable<T> Children { get; }
}
I then have the following interfaces which derive from the interface above:
public interface ISiteMapNode<T> : ISiteMapNode where T : ISiteMapNode<T> { }
public interface ISiteMapNode : IHierarchical<ISiteMapNode> {
string Name { get; set; }
}
Finally I have the following implementation:
public class SiteMapNode : ISiteMapNode<SiteMapNode> {
public string Name { get; set; }
public ISiteMapNode Parent { get; }
public IEnumerable<ISiteMapNode> Children { get; }
}
Now I have a method which takes an argument of type ISiteMapNode and tries to set the Parent property. Obviously this won't work as the Parent property is readonly. I had to remove set to make the IHierachical interface covariant. Is there any way I can do this?
回答1:
No you cannot.
You can think of the out keyword before a type argument as saying that the declared interface will only return (or output) values of the specified type. This is analogous to the in keyword saying that the declared interface will only accept values of the specified type as input.
out = values are ONLY going outin = values are ONLY going in
Covariant type parameter:
interface IHierarchical<out T>
{
T Parent
{
get; // OK -- it's going out
set; // ERROR
}
}
Contravariant type parameter:
interface IHierarchical<in T>
{
T Parent
{
get; // ERROR
set; // OK -- it's going in
}
}
Invariant type parameter: (normal)
interface IHierarchical<T>
{
T Parent
{
get; // OK
set; // OK
}
}
One alternative could be to split the interface into a covariant and a contravariant subinterface. Something like this:
interface IHierarchical<T> : IHierarchicalIn<T>, IHierarchicalOut<T>
{
}
interface IHierarchicalIn<in T>
{
T Parent { set; }
}
interface IHierarchicalOut<out T>
{
T Parent { get; }
}
class Node : IHierarchical<Node>
{
public Node Parent
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
}
I don't really see a use for that though.
来源:https://stackoverflow.com/questions/26276231/set-property-on-a-covariant-interface