如何在c#泛型类中找到用于泛型函数的底层类型

本文关键字:函数 泛型 类型 用于 泛型类 | 更新日期: 2023-09-27 17:54:15

假设我有一个c#类型:

class MyType<T>
{
   T Value { get; set; }
   // etc.
}

和一些特殊类型:

class MyTypeString : MyType<string>
{
   // etc.
}

class MyTypeDate : MyType<Date>
{
   // etc.
}

我想写一个泛型函数,我将能够操作(甚至创建)类型为MyTypeStringMyTypeDate的对象,并在同一时间返回/修改底层类型值(stringDate)。

我目前的解决方案是这样的:

T_Underlying Foo<T, T_Underlying>(ref T p_variable, T_Underlying p_value)
        where T : MyType<T_Underlying>, new()
{
    if(p_variable == null)
    {
        p_variable = new T() ;
    }
    p_variable.Value = p_value ;
    return p_value ;
}

但是这个解决方案对我来说太啰嗦了,因为要调用这个方法,我需要提供所有类型,包括主体类型和底层类型:

MyTypeString myTypeString = null ;
string value ;
value = Foo<MyTypeString, string>(ref myTypeString, "Hello World") ;

在c#中是否有一种方法可以使以下行成为可能?

value = Foo<MyTypeString>(ref myTypeString, "Hello World") ;

或偶数:

value = Foo(ref myTypeString, "Hello World") ;

? ?

<我>注:: MyTypeStringstring上的泛型,所以我有预感MyTypeString应该能够给我它的底层类型,但是虽然我知道如何在c++中做到这一点,但我不知道如何在c#中做到这一点,或者即使它是可能的。

<我> P.P.S.:我知道这个例子很愚蠢,但是在实际代码中有一个Setter和Getter,从而解释了Foo的"set和get"的外观和感觉。

编辑

如上所述,我混合了Getter/Setter来问这个问题,没有意识到问题出在Getter上:

T_Underlying Get<T, T_Underlying>(ref T p_variable)
        where T : MyType<T_Underlying>, new()
{
    if(p_attributeMember == null)
    {
        return default(T_Underlying) ;
    }
    return p_attributeMember.Value ;
}

错误(在Monodevelop for Ubuntu 10.10,即c# 3.5)为:

错误CS0411:方法' MyType '的类型参数。Get(ref T)'不能从用法中推断出来。尝试显式指定类型参数(CS0411)

但是我猜Magnus的答案可以帮助我在那里,或者我将改变Getter的原型,把返回值作为第二个out参数。

如何在c#泛型类中找到用于泛型函数的底层类型

c#在泛型中有类型推断方法,所以你可以只写

value = Foo(ref myTypeString, "hello world");

使用当前解决方案

oxilumin是对的,您当前的解决方案已经按照您的要求工作了。但是要回答您关于如何获得底层泛型类型的问题:

var type = p_variable.GetType().BaseType.GetGenericArguments()[0];

您是否尝试过使用typeof关键字来获取类型?