重写抽象只读属性以读取/写入属性
我想只强制执行基本抽象类的给定属性上的C#getter。派生类可以,如果他们想要的话,也可以为该属性提供一个setter用于静态绑定类型的公共使用。重写抽象只读属性以读取/写入属性
鉴于以下抽象类:
public abstract class Base
{
public abstract int Property { get; }
}
如果我想要一个派生类还实现了一个二传手,我天真地尝试:
public class Derived : Base
{
public override int Property
{
get { return field; }
set { field = value; } // Error : Nothing to override.
}
private int field;
}
但后来我得到一个语法错误,因为我尝试覆盖不存在的setter。我尝试了一些其他方式,比如声明基本setter是私人的,而且我仍然偶然发现了阻止我这样做的所有错误。必须有办法做到这一点,因为它不会破坏任何基础合同。另外,它可以通过接口完成,但我真的需要这个默认实现。我想知道是否有一个隐藏的C#语法技巧来做到这一点,否则我只会忍受它并实现手动SetProperty()方法。
你不能直接这样做,因为你不能在相同的类型上使用相同的签名new
和override
;有两种选择 - 如果你控制的基类,添加秒属性:
public abstract class Base
{
public int Property { get { return PropertyImpl; } }
protected abstract int PropertyImpl {get;}
}
public class Derived : Base
{
public new int Property {get;set;}
protected override int PropertyImpl
{
get { return Property; }
}
}
否则,您能介绍的类层次结构的额外级别:
public abstract class Base
{
public abstract int Property { get; }
}
public abstract class SecondBase : Base
{
public sealed override int Property
{
get { return PropertyImpl; }
}
protected abstract int PropertyImpl { get; }
}
public class Derived : SecondBase
{
public new int Property { get; set; }
protected override int PropertyImpl
{
get { return Property; }
}
}
什么是这样的:
public abstract class Base
{
public virtual int Property
{
get { return this.GetProperty(); }
set { }
}
protected abstract int GetProperty();
}
任何继承者现在必须重写他们两个 - 有点多余? – 2009-09-28 21:24:35
仅限于覆盖该属性。否则,没有虚拟财产,实际上可能是一个可以接受的选择。 – Coincoin 2009-09-28 21:34:28
如果你不覆盖属性,这个集合的目的是非常不寻常的。 – 2009-09-28 21:38:57
这是否适合您的需求?
public abstract class TheBase
{
public int Value
{
get;
protected set;
}
}
public class TheDerived : TheBase
{
public new int Value
{
get { return base.Value; }
set { base.Value = value; }
}
}
的virtual
除去,但是基准值仍然为值的唯一存储设备。所以这应该显示'5'。而编译器应该计较b.Value = 4;
TheDerived d = new TheDerived();
d.Value = 5;
TheBase b = d;
//b.Value = 4; // uncomment for compiler error
cout << "b.Value == " << b.Value << endl;
-Jesse
我有地方,我需要的接口,以便能够在两个松散的相关类之间有着共同的排序功能类似的要求。其中一个具有只读Order属性,另一个具有读写Order属性,但我需要一种以同样方式从两个类读取属性的方法。
事实证明,这可以通过在派生接口中隐藏只读值来完成。这是我如何做到的。
interface ISortable
{
int Order { get; }
}
interface ISortableClass2
: ISortable
{
// This hides the read-only member of ISortable but still satisfies the contract
new int Order { get; set; }
}
class SortableClass1
: ISortable
{
private readonly int order;
public SortableClass1(int order)
{
this.order = order;
}
#region ISortable Members
public int Order
{
get { return this.order; }
}
#endregion
}
class SortableClass2
: ISortableClass2
{
#region ISortableClass2 Members
public int Order { get; set; }
#endregion
}
class RunSorting
{
public static void Run()
{
// Test SortableClass1
var list1 = new List<SortableClass1>();
list1.Add(new SortableClass1(6));
list1.Add(new SortableClass1(1));
list1.Add(new SortableClass1(5));
list1.Add(new SortableClass1(2));
list1.Add(new SortableClass1(4));
list1.Add(new SortableClass1(3));
var sorted1 = SortObjects(list1);
foreach (var item in sorted1)
{
Console.WriteLine("SortableClass1 order " + item.Order);
}
// Test SortableClass2
var list2 = new List<SortableClass2>();
list2.Add(new SortableClass2() { Order = 6 });
list2.Add(new SortableClass2() { Order = 2 });
list2.Add(new SortableClass2() { Order = 5 });
list2.Add(new SortableClass2() { Order = 1 });
list2.Add(new SortableClass2() { Order = 4 });
list2.Add(new SortableClass2() { Order = 3 });
var sorted2 = SortObjects(list2);
foreach (var item in sorted2)
{
Console.WriteLine("SortableClass2 order " + item.Order);
}
}
private static IEnumerable<T> SortObjects<T>(IList<T> objectsToSort) where T : ISortable
{
if (objectsToSort.Any(x => x.Order != 0))
{
return objectsToSort.OrderBy(x => x.Order);
}
return objectsToSort;
}
}
交叉链接:http://stackoverflow.com/questions/2243886/make-a-read-only-property-writable-in-the-derived-class – Mikhail 2011-04-06 10:47:49