C# 将派生类的实体传递给泛型方法

C# 将派生类的实体传递给泛型方法,c#,generics,inheritance,C#,Generics,Inheritance,我有四门课,比如: 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

我有四门课,比如:

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
}
static void Main(字符串[]args)
{
var derivedB=新的derivedB();
derivedB.SomeProperty=新的DerivedA();
SomeMethod(derivedB);
}
静态方法(T参数),其中T:BaseB
{
var tmp1=param.SomeProperty;//null
var tmp2=(参数为DerivedB).SomeProperty;//必需值
var tmp3=(参数为T).SomeProperty;//null
}
如果我传入
SomeMethod
一个类型为
DerivedB
的参数,param有两个属性
SomeProperty
——基本类和派生类类型。但是,无论什么类型是
param
,它都被视为
BaseB
类,我必须显式地将其转换为所需类型,以获得正确的
SomeProperty
值。投T也没用。 我应该将param变量强制转换为它自己的类型,还是至少可以获得一个非null值的属性

但无论什么类型是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;
}
static void somethod(T参数),其中T:BaseB
{
动态d=参数;
//这将使用param的执行时间类型
var tmp1=d.SomeProperty;
}

但如果可能的话,我会完全避免这种设计。或者具有单独命名的属性,因此它们显然是独立的,或者具有单个状态的属性,可以根据实例的“视图”进行不同的访问(如果将属性设置为“错误”类型,则可能会出现异常).

您需要的是将泛型转换为type
class
,而不是
BaseB
并将参数类型设置为动态。这将在运行时处理引用

static void SomeMethod<T>(T param) where T : class
        {
            dynamic tmp1 = param; 
            var myProperty = tmp1.SomeProperty;
        }
static void SomeMethod(T参数),其中T:class
{
动态tmp1=参数;
var myProperty=tmp1.SomeProperty;
}
另外,我认为这里是否真的需要阴影

此外,还可以删除泛型的类型。它在你的情况下仍然有效

只是

静态方法(T参数)

隐藏基本属性可能不是最好的方法

对于您的小样本,基类和派生类都是空的,因此要准确地确定您需要什么是有点困难的

我们想到了两种更干净、更简单的方法:

  • 考虑创建一个基类、派生类和泛型类型(在SomeMethod中使用)都将实现的接口。。。然后就相当容易了

  • >P>如果公共接口不可能满足您的需要,请考虑将基类创建为泛型类


希望这对您有所帮助

您在derivedB中隐藏baseB属性是导致所有这些问题的原因。为什么不让baseB的属性也通用呢?可能是
static void SomeMethod<T>(T param)