如何将显式子类型作为属性

时间:2014-12-04 08:04:02

标签: c# properties

我们说我有一个班级:

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是一个视图。

2 个答案:

答案 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属性。但我厌恶成员隐藏和恕我直言,这里所做的一切都是让代码更加混乱。