简体   繁体   English

如何在 C# 通用 class 中找到要在通用 function 中使用的基础类型?

[英]How to find the underlying type in a C# generic class to be used in a generic function?

Let's say I have a C# type:假设我有一个 C# 类型:

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

And some specialized types:还有一些专门的类型:

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


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

I want to write a generic function where I will be able to manipulate (and even create) objects of type MyTypeString or MyTypeDate , and at the same time return/modify the underlying type value ( string or Date ).我想编写一个通用的 function ,我将能够在其中操作(甚至创建) MyTypeStringMyTypeDate类型的对象,同时返回/修改基础类型值( stringDate )。

My current solution is something like:我目前的解决方案是这样的:

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 ;
}

But this solution is too much verbose for my taste, as to call the method, I need to provide all types, both the principal and the underlying type:但是这个解决方案对我来说太冗长了,至于调用方法,我需要提供所有类型,包括主体类型和底层类型:

MyTypeString myTypeString = null ;
string value ;

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

Is there a way in C# to make the following line possible? C# 中有没有办法使以下行成为可能?

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

Or even:甚至:

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

??? ???

PS: MyTypeString is a generic on string , so I have a hunch MyTypeString should be able to give me its underlying type, but while I know how to do it in C++, I don't know how to do it in C#, or even if it is possible. PS: MyTypeStringstring上的泛型,所以我有预感MyTypeString应该能够给我它的底层类型,但是虽然我知道如何在 C++ 中做到这一点,但我不知道如何在 C# 中做到这一点,甚至如果有可能。

PPS: The example is dumb, I know, but in the real code have both a Setter and a Getter, thus explaining the "set and get" look and feel of Foo. PPS:这个例子很愚蠢,我知道,但在实际代码中同时有一个 Setter 和一个 Getter,从而解释了 Foo 的“设置和获取”外观。

Edit编辑

As written above, I mixed both my Getter/Setter to ask this question, without realizing the problem was with the Getter:如上所述,我混合了我的 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 ;
}

The error (On Monodevelop for Ubuntu 10.10, ie C# 3.5) was:错误(关于 Ubuntu 10.10 的 Monodevelop,即 C# 3.5)是:

Error CS0411: The type arguments for method `MyType.Get(ref T)' cannot be inferred from the usage.错误 CS0411:无法从用法中推断方法“MyType.Get(ref T)”的类型 arguments。 Try specifying the type arguments explicitly (CS0411)尝试明确指定类型 arguments (CS0411)

But I guess Magnus's answer could help me there, or I would change the prototype of the Getter to put the returned value as second out parameter.但我想Magnus 的回答可以帮助我,或者我会更改 Getter 的原型以将返回的值作为第二个out参数。

C# has Type inference in generics method so you can write just C# 在 generics 方法中具有类型推断,因此您可以只编写

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

using your current solution.使用您当前的解决方案。

oxilumin is right, your current solution already works as you want. oxilumin 是对的,您当前的解决方案已经如您所愿。 But to answer your question on how to get the underlying generic type:但是要回答您有关如何获取底层泛型类型的问题:

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

Have you tried using the typeof keyword to get the type?您是否尝试过使用typeof关键字来获取类型?

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

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