简体   繁体   English

限制对继承属性的访问的最佳方法是什么?

[英]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 ,因为我还需要阻止类本身访问该属性并强制其使用PriceAPriceB 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM