是否可以将派生类的属性参数传递给其基类?
基本上,我正在尝试从派生类中设置属性的属性参数。
如何在C ++中完成
public class HasHistory<T, string name> {
public HasHistory() {
History=new History<T>();
}
// here's my attribute
[BsonElement(name)]
public History<T> History {
get;
protected set;
}
}
但是,非类型模板参数在C ++中是合法的,但在C#中是非法的。
C#中的意外解决方法
我意识到我可以将属性设为虚拟,并在派生类中添加属性。但是后来我会在构造函数中调用一个虚函数,虽然这可能有用,但这种做法很糟糕。
我确实想进行调用,因为我希望基类构造函数初始化成员;这实际上是基类的重点。
public class HasHistory<T> {
public HasHistory() {
// this will be called before Derived is constructed
// and so the vtbl will point to the property method
// defined in this class.
// We could probably get away with this, but it smells.
History=new History<T>();
}
// here's my property, without an Attribute
public virtual History<T> History {
protected set;
get;
}
}
public class Derived: HasHistory<SomeType> {
// crap! I made this virtual and repeated the declaration
// just so I could add an attribute!
[BsonElement("SomeTypeHistory")]
public virtual HasHistory<SomeType> History {
protected set;
get;
}
}
所以我想我不能把属性放在基类中,而是将它放在派生类属性上,该属性使用/是根据受保护的基类属性实现的,但这很麻烦,它可以避免任何方便使用基类。
所以这是一个很好的方法,对吗?对?
如何在派生类的属性上重新定义属性,该属性继承自派生类中的基础 WITHOUT覆盖属性?
答案 0 :(得分:0)
更新: Darn,你已经考虑过了。我应该在发布前更新:)
不幸的是,你想做的事情远远超出C#属性机制的范围。泛型与模板不同,因此这种解决方法与它一样好。
大多数情况下,无论如何你都要在顶层定义一个属性,所以通常这不是问题。当 出现问题时 - 显然在您的情况下 - 那么您必须使用丑陋的解决方法。
以下原始答案......
如果我正确理解了这个例子,你想要根据派生类型中/中声明的某个值将属性应用于类成员。由于C#不支持泛型的非类型参数,因此您需要另一种方法来执行此操作。
您可以做的一件事是覆盖后代类中的属性,如下所示:
public class HasHistory<T>
{
public HasHistory()
{
History = new History<T>();
}
public virtual History<T> History { get; protected set; }
}
public class MyHistory<T> : HasHistory<T>
{
public MyHistory()
: base()
{}
[BSONElement("some name")]
public override History<T> History
{
get
{
return base.History;
}
protected set
{
base.History = value;
}
}
}
使用BsonElement
属性的代码将使用派生的HasHistory<T>
实例的实际类型,因此它将查看最后定义的属性virtual
链的。{根据上面的代码,如果我创建一个MyHistory<T>
实例并将其传递给BSON序列化程序,它将在History
类中找到附加到MyHistory<T>
属性的属性。
但是,您可以在基础级别定义属性,并在必要时在派生类中覆盖它。不确定这对你的情况是否有用。
这是更多的工作,特别是因为您必须在每个派生类中执行此操作,但我认为这与您在这种情况下将要使用C ++模板样式一样接近。但我很高兴被证明是错的:)