繁体   English   中英

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

[英]Passing entity of derived class to generic methods

我有四个班级:

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变量转换为其自己的类型,还是可以至少获得一个非空值的属性?

但是无论参数是什么类型,它都被视为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;
}

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

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

static void SomeMethod<T>(T param) where T : class
        {
            dynamic tmp1 = param; 
            var myProperty = tmp1.SomeProperty;
        }

另外,我不认为这里是否真的需要阴影。

此外,您可以删除通用类型。 它仍然可以在您的情况下工作

只是

static void SomeMethod<T>(T param)

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

对于您的小样本,基类和派生类为空,因此弄清楚您到底需要什么有点棘手。

有两种更简便的方法:

  • 考虑创建一个接口,该接口将基类,派生类和泛型类型(在SomeMethod中使用)都实现...然后相当简单

  • 如果无法满足您的需求,请考虑将基类创建为泛型类

希望这可以帮助

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM