CDove
CDove

Reputation: 1950

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. That's because in class Bar, there are two prices and both need to be restricted to type 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. 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. When an inherited class needs access to a specific property blocked at design-time, what is the proper way to restrict that access?

Upvotes: 0

Views: 56

Answers (2)

MakePeaceGreatAgain
MakePeaceGreatAgain

Reputation: 37000

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. However Bar would just implement the first one while all other classes implement the second one:

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 { ... }

Upvotes: 3

Patrick Hofman
Patrick Hofman

Reputation: 156978

You could create an override for the Price property and mark that one [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 :(

Upvotes: 3

Related Questions