我们说我有一个班级:
class AbstractPerson{
AbstractAttribute attr {get; set;}
}
现在,在AbstractPerson的子类中,我想使用attr,但在特殊情况下如此:
class Pilot: AbstractPerson {
...
(attr as SpecialAttribute).pilotID;
...
}
因为我不想这样做,所以每当我拨打attr
时,我都希望在Pilot
中有一个属性,它会返回attr
的类型版本,但是我没有让它上班。
所以,这不起作用:
class Pilot: AbstractPerson {
AbstractAttribute attr {
get
{
return (attr as SpecialAttribute);
}
set;
}
}
这甚至可能吗?
***按照惯例,我知道" attr"应该在PascalCase中,我只是忘了这个例子。实际上,Person是一个控制器,而attr是一个视图。
答案 0 :(得分:1)
假设:
class SpecialAttribute : AbstractAttribute {}
您可以使用泛型:
class AbstractPerson<T>
where T : AbstractAttribute
{
T attr {get; set;}
}
class Pilot: AbstractPerson<SpecialAttribute>
{
/* ... */
void Foo()
{
// attr is a SpecialAttribute here
attr.PropertyOfSpecialAttribute = "bar";
}
}
请注意,您误导了as
运营商
如果有可能attr
不是SpecialAttribute
,则as
必须后跟空检查:
var foo = bar as Foo;
if (foo != null)
{
// do something
}
否则(如果attr
必须为SpecialAttribute
),则必须使用类型转换:
var foo = (Foo)bar;
如果不期望类型,则抛出InvalidCastException
。
答案 1 :(得分:1)
在这种情况下,我更喜欢丹尼斯的建议。也就是说,您可能无法更改基类来使用它。如果是这样,那么你可以做一些不太好但仍然有用的事情:
class AbstractPerson
{
AbstractAttribute Attribute { get; set; }
}
class Pilot : AbstractPerson
{
PilotAttribute PilotAttribute
{
get { return (PilotAttribute)AbstractAttribute; }
set { AbstractAttribute = value; }
}
}
自然地,这种方法要求PilotAttribute
实际上来自AbstractAttribute
,这在通用解决方案中实际上并不需要(除非您特别希望它)。它也没有提供通用解决方案所具有的安全级别:AbstractAttribute
仍然存在,并且可以分配不属于PilotAttribute
类型的值。所以你必须小心不要这样做(最好避免在处理Pilot
的实例时使用base属性。)
也可以使用新属性隐藏基本AbstractAttribute
属性。但我厌恶成员隐藏和恕我直言,这里所做的一切都是让代码更加混乱。