What I want to achieve is the following : I have a property declared in the BaseClass. If this property is accessed via the base class' pointer, only the getter should be available but if the derived class pointer is used I want to be able to get and set the property. So the intellisense should not even show a setter for the base pointer.
public class BaseClass
{
public virtual int MyProperty
{
get { return 1; }
set {;}//This would show the setter in Intellisense
}
}
public class DerivedClass : BaseClass
{
int intValue;
public override int MyProperty
{
set { intValue = value;}
}
}
A realistic example:
Consider a situation where you have a Parent and Child class derived from the Person class. Imagine a property -RestrictionLevel, where both can read it but only the parent can set the value. Is there a better way to design this situation?
The only way I could think of is to shadow the property with a new one:
public class DerivedClass : BaseClass
{
int intValue;
public new int MyProperty
{
get { return intValue; }
set { intValue = value; }
}
}
Notice how the property is declared new
instead of override
. This means, of course, that MyProperty
of the type DerivedClass
has nothing to do with MyProperty
of the type BaseClass
, it's a brand new property that just happens to have the same name (thus hiding the one from the base class).
The result is this:
DerivedClass d = new DerivedClass();
d.MyProperty = 42;
BaseClass b = new DerivedClass();
b.MyProperty = 42; /* compilation error: Property or indexer
'TheNamespace.BaseClass.MyProperty'
cannot be assigned to -- it is
read only */
Also, as @silky states in the comment:
(though I suggest you make it, and the parent, refer to the same variable to avoid a very confusing situation) but I really don't think this would ever be appropriate.
...you may want to have the new property access the one from the base class (through base.MyProperty
, completed with a protected setter). Consider the following for instance:
DerivedClass d = new DerivedClass();
d.MyProperty = 42;
BaseClass b = d;
Console.WriteLine(b.MyProperty); // prints 1
That said, I always feel a little dirty when using new
(which, when I think about it, I am not sure that I have actually done in production code).
Update
Given the example scenario that you give (that I interpret in a way that a Parent
is to be able to set the RestrictionLevel
of a Child
), it could be solved like this:
public enum RestrictionLevel
{
Low,
Medium,
Grounded
}
public class Person
{
public RestrictionLevel RestrictionLevel { get; private set; }
protected static void SetRestrictionLevelInternal(Person person, RestrictionLevel restrictionLevel)
{
person.RestrictionLevel = restrictionLevel;
}
}
public class Child : Person { }
public class Parent : Person
{
public void SetRestrictionLevel(Child child, RestrictionLevel restrictionLevel)
{
SetRestrictionLevelInternal(child, restrictionLevel);
}
}
This means that the following code is valid:
Child c = new Child();
Parent p = new Parent();
p.SetRestrictionLevel(c, RestrictionLevel.Grounded);
...but this one is not:
Child c = new Child();
c.SetRestrictionLevel(c, RestrictionLevel.Low);
The method SetRestrictionLevelInternal
can be called from within any descendant type (including Child
), but cannot be invoked from outside the type itself. So, you cannot invoke SetRestrictionLevelInternal
on a Parent
instance. In the above example, we choose to expose a public
method, which in turn invokes the protected
method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With