Reputation: 1950
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
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
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