我有四个类,如:
class BaseA { }
public class DerivedA : BaseA { }
public class BaseB
{
public BaseA SomeProperty { get; set; }
}
public class DerivedB : BaseB
{
public new DerivedA SomeProperty { get; set; }
}
用于以下程序:
static void Main(string[] args)
{
var derivedB = new DerivedB();
derivedB.SomeProperty = new DerivedA();
SomeMethod(derivedB);
}
static void SomeMethod<T>(T param) where T : BaseB
{
var tmp1 = param.SomeProperty; // null
var tmp2 = (param as DerivedB).SomeProperty; // required value
var tmp3 = (param as T).SomeProperty; // null
}
如果我传入SomeMethod
DerivedB
类型的参数,则param有2个属性SomeProperty
- 基类和派生类类型。但无论param
是什么类型,它都被视为BaseB
类,我必须明确地将其转换为必需的类型以获得正确的SomeProperty
值。施放到T没有帮助。
我应该将param变量强制转换为自己的类型,还是至少可以获得一个非空值的属性?
答案 0 :(得分:0)
但无论param是什么类型,它都被视为BaseB类,我必须将其显式地转换为必需的类型才能获得正确的SomeProperty值。
是。因为该绑定是在编译时执行的,所以编译器只知道BaseB.SomeProperty
。这是将在IL中引用的属性,以及将在执行时获取的属性。
我认为拥有两个具有相同名称的独立属性实在令人困惑。如果确实想要这样做,您可以强制在执行时进行绑定,而不是使用动态类型:
static void SomeMethod<T>(T param) where T : BaseB
{
dynamic d = param;
// This will use the execution-time type of param
var tmp1 = d.SomeProperty;
}
但是如果可能的话,我会完全避免这种设计。要么具有单独命名的属性,所以它们显然是独立的,或者具有单个状态的属性,可以根据实例的“视图”以不同方式访问(如果您有异常风险)将属性设置为“错误”类型。)
答案 1 :(得分:0)
您需要的是将通用转换为class
而不是BaseB
并且参数类型为动态。这将处理引用运行时。
static void SomeMethod<T>(T param) where T : class
{
dynamic tmp1 = param;
var myProperty = tmp1.SomeProperty;
}
此外,我不认为这里是否真的需要遮蔽。
此外,您可以删除通用类型。它仍将适用于您的情况
只是
static void SomeMethod<T>(T param)
答案 2 :(得分:0)
隐藏基本属性可能不是最好的方法。
使用您的小样本,基类和派生类是空的,因此找出您需要的内容有点棘手。
有两种更清洁,更简单的方法:
考虑创建一个接口,基类,派生类和泛型类型(在SomeMethod中使用)都将实现...然后它很容易
如果您的需求无法使用通用接口,请考虑将基类创建为通用类
希望这有帮助