为什么我不能同时覆盖和新建一个Property(C#)?

根据这个问题,你似乎可以为方法做到这一点。 我想知道的是当我尝试使用属性时它不起作用的原因。

public class Foo { public virtual object Value { get; set; } } public class Foo : Foo { public override object Value { get { return base.Value; } set { base.Value = (T)value; //inject type-checking on sets } } public new T Value { get { return (T)base.Value; } set { base.Value = value; } } } 

来自C#4.0 RC1的错误消息

错误1类型’ClassLibrary1.Foo’已包含’Value’ClassLibrary1 \ Class1.cs的定义31 22 ClassLibrary1

您不能使用相同名称的两个属性。 这在C#中是不允许的。 唯一的例外是索引器,因为在索引器的情况下,签名会按索引类型更改。

对于仅因返回类型而不同的方法,您不能重载。 具有单个名称的属性基本上被同一规则禁止,因为它在内部是一对没有get访问器参数的方法。

如果您执行以下操作,则可以执行此操作…

 public interface IFoo { T Value { get; set; } } public class Foo : Foo, IFoo { T IFoo.Value { get { return (T)base.Value; } set { base.Value = value; } } } 

唯一的问题是,当你引用时你必须使用接口类型…即

  IFoo myfoo = new Foo(); int result = myFoo.Value; //This will give you the typed version Foo myfoo = new Foo(); int result = myFoo.Value; //This will give throw an exception 

即使C#不能,C ++ / CLI也能做到。 在C ++ / CLI中,您可以明确说明要覆盖哪个方法,因此名称不必匹配。

你可以通过interace获得这个。

 public interface IFoo { object Value { get; set; } } public class Foo : IFoo { object _value = null; object IFoo.Value { get { return _value; } set { _value = value; } } public T Value { get; set; } } 

根本问题是永远不知道要使用哪个属性。

例如,

 Foo s = new Foo(); s.Value = "hmmm"; 

那么应该使用哪个属性? int派生自object,也符合通用属性版本的约束。

您有两个相同属性的定义Value由override覆盖…和一个由new定义。 返回类型不是方法签名中的区别特征,即如果签名仅在返回类型中不同,则签名被认为是相同的。 所以,使用override或new。

在您的情况下,您可以使用new而不是override来实现目标。 但是,在使用new时,您始终必须考虑执行的具体取决于您调用方法的类型。 即

 var foo = new Foo(); var foo_ = new Foo(); foo.Value // calls the implementation on Foo foo_.Value // calls the implementation on Foo ((Foo) foo).Value // calls the implementation on Foo