Reputation: 391
Let's say I have a Class:
class AbstractPerson{
AbstractAttribute attr {get; set;}
}
Now, in the child Class of AbstractPerson, I want to use the attr but, in the special case like so:
class Pilot: AbstractPerson {
...
(attr as SpecialAttribute).pilotID;
...
}
Because I don't want to do this, everytime I call attr
, I want to have a property in Pilot
that gives back a typecasted version of attr
, but I'm not getting this to work.
So, this doesn't work:
class Pilot: AbstractPerson {
AbstractAttribute attr {
get
{
return (attr as SpecialAttribute);
}
set;
}
}
Is this even possible?
*** I know that by convention, "attr" should be in PascalCase, I just forgot for this example. In reality the Person is a Controller and the attr a View.
Upvotes: 0
Views: 45
Reputation: 70691
In this kind of situation, I prefer Dennis's suggestion. That said, you may not be able to change the base class to use it. If that's the case, then you can do something not quite as good but still useful:
class AbstractPerson
{
AbstractAttribute Attribute { get; set; }
}
class Pilot : AbstractPerson
{
PilotAttribute PilotAttribute
{
get { return (PilotAttribute)AbstractAttribute; }
set { AbstractAttribute = value; }
}
}
Naturally, this approach requires that PilotAttribute
actually derive from AbstractAttribute
, something that is not actually required in the generic solution (unless you specifically want it to be). It also does not provide the level of security that the generic solution does: the AbstractAttribute
is still present and could be assigned a value not of the PilotAttribute
type. So you do have to be careful to not do that (preferably by avoiding using the base attribute when dealing with instances of Pilot
).
It is also possible to simply hide the base AbstractAttribute
property with a new one. But I detest member hiding and IMHO all that would do here is make the code more confusing.
Upvotes: 1
Reputation: 37780
Assuming, that:
class SpecialAttribute : AbstractAttribute {}
You can use generics:
class AbstractPerson<T>
where T : AbstractAttribute
{
T attr {get; set;}
}
class Pilot: AbstractPerson<SpecialAttribute>
{
/* ... */
void Foo()
{
// attr is a SpecialAttribute here
attr.PropertyOfSpecialAttribute = "bar";
}
}
Note, that you're misusing as
operator.
If there is a possibility, that attr
isn't a SpecialAttribute
, than as
must be followed by null-checking:
var foo = bar as Foo;
if (foo != null)
{
// do something
}
Otherwise (if attr
must be SpecialAttribute
), you must use type casting:
var foo = (Foo)bar;
to throw InvalidCastException
, if the type is not expected.
Upvotes: 1