[英]What is the best method for restricting access to an inherited property?
Given: 鉴于:
public class Foo
{
....//other properties
public double Price { get; set;}
.....//methods
}
I have multiple classes which inherit from this class. 我有多个从此类继承的类。 In the case of only one class,
Price
cannot be used. 在仅一类的情况下,不能使用
Price
。 That's because in class Bar
, there are two prices and both need to be restricted to type long
. 这是因为在
Bar
类中,有两个价格,并且两个价格都必须限制为long
类型。 For now, I'm just throwing exceptions. 现在,我只是抛出异常。 Keep in mind that all other properties are accessible;
请记住,所有其他属性都可以访问; only this one is affected:
仅此一项受到影响:
public class Bar : Foo
{
....//other properties
public long PriceA { get; set;}
public long PriceB { get; set;}
public new double Price
{
get
{
throw new Exception("NO NO NO");
}
set
{
throw new Exception("NO NO NO");
}
}
.....//methods
}
This feels dirty, especially since the only thing preventing a developer from mistakenly using Price
is a runtime exception. 这感觉很脏,尤其是因为唯一防止开发人员错误使用
Price
事情是运行时异常。 I can't just declare it private
, as I also need to prevent the class itself from accessing the property and force it to use PriceA
or PriceB
. 我不能仅仅将其声明为
private
,因为我还需要阻止类本身访问该属性并强制其使用PriceA
或PriceB
。 When an inherited class needs access to a specific property blocked at design-time, what is the proper way to restrict that access? 当继承的类需要访问在设计时被阻止的特定属性时,限制该访问的正确方法是什么?
You could create an override for the Price
property and mark that one [Obsolete]
. 您可以为
Price
属性创建一个替代,并将其标记为[Obsolete]
。 That will help in most cases to filter out problems. 在大多数情况下,这将有助于滤除问题。 Next to the exception it will cover all situations you might end up using it.
除了例外情况,它将涵盖您可能最终使用它的所有情况。
That said, I personally think it is bad design . 就是说, 我个人认为这是不好的设计 。 If you don't need the field, maybe it shouldn't override the base class at all, but that might be hard in some cases.
如果您不需要该字段,则也许它根本不应该覆盖基类,但是在某些情况下这可能很难。
Proposed code solution: 建议的代码解决方案:
public class Foo
{
public virtual double Price { get; set; }
}
public class Bar : Foo
{
[Obsolete]
public override double Price { get; set; }
}
Bar b = new Bar();
b.Price = 1; // warning
Foo f = new Bar();
f.Price = 1; // no warning :(
When all your implementation does is to say "don´t call me" than it shouldn´t have that implementation. 当您执行的所有操作都是说“不要叫我”时,则不应执行该操作。 In your case this means it shouldn´t derive from a base-class which has that member.
在您的情况下,这意味着它不应衍生自具有该成员的基类。
If your base-class has a member defined this member belongs to the contract this class has to the outside- The same should apply for all its derived classes, it is weird to say all derived classes have a member derived from their base-class but only a few of them have it appropriately implemented and can thus be used. 如果您的基类定义了一个成员,则该成员属于该类与外部之间的合同-同样,该类也适用于其所有派生类,奇怪的是,所有派生类都有一个从其基类派生的成员,但是他们中只有少数人适当地实施了它,因此可以使用。 The contract however states: all classes implementing it (that is all classes that inherit the base-class) implement it completely , not just partly .
但是,合同规定:实现它的所有类(即继承基类的所有类)都完全实现它,而不仅仅是部分实现 。
Having said this what you´re trying to do is a bad idea. 说了这些,您想做的就是一个坏主意。
A better desing would be to extract a common interface for all classes, and one interface with the Price
-property. 更好的方法是为所有类提取一个公共接口,并为一个带有
Price
属性的接口。 However Bar
would just implement the first one while all other classes implement the second one: 但是
Bar
只会实现第一个,而其他所有类都将实现第二个:
interface IBar { /* common properties */ }
interface IFoo : IBar
{
double Price { get; set; }
}
class Bar : IBar
{
public long PriceA { get; set;}
public long PriceB { get; set;}
}
class Foo : IFoo { ... }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.