假设我有一个C#类型:
class MyType<T>
{
T Value { get; set; }
// etc.
}
Run Code Online (Sandbox Code Playgroud)
还有一些特殊的类型:
class MyTypeString : MyType<string>
{
// etc.
}
class MyTypeDate : MyType<Date>
{
// etc.
}
Run Code Online (Sandbox Code Playgroud)
我想编写一个通用的功能,我就能操纵(甚至创建)类型的对象MyTypeString或MyTypeDate,并在同一时间返回/修改底层类型值(string或Date).
我目前的解决方案是这样的:
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 ;
}
Run Code Online (Sandbox Code Playgroud)
但是这个解决方案对我来说太冗长了,因为调用方法,我需要提供所有类型,包括主体和底层类型:
MyTypeString myTypeString = null ;
string value ;
value = Foo<MyTypeString, string>(ref myTypeString, "Hello World") ;
Run Code Online (Sandbox Code Playgroud)
在C#中是否有办法使下一行成为可能?
value = Foo<MyTypeString>(ref myTypeString, "Hello World") ;
Run Code Online (Sandbox Code Playgroud)
甚至 :
value = Foo(ref myTypeString, "Hello World") ;
Run Code Online (Sandbox Code Playgroud)
???
PS:MyTypeString是一个通用的string,所以我有预感MyTypeString应该能够给我它的底层类型,但虽然我知道如何在C++中做,我不知道如何在C#中做到,或者即使它是可能.
PPS:我知道,这个例子很愚蠢,但是真正的代码中有一个Setter和一个Getter,因此解释了Foo的"set and 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 ;
}
Run Code Online (Sandbox Code Playgroud)
错误(On Monodevelop for Ubuntu 10.10,即C#3.5)是:
错误CS0411:无法从用法推断出方法"MyType.Get(ref T)"的类型参数.尝试明确指定类型参数(CS0411)
但我猜Magnus的答案可以帮助我,或者我会更改Getter的原型以将返回的值作为第二个out参数.
oxilumin 是对的,您当前的解决方案已经按您想要的方式工作。但要回答有关如何获取底层泛型类型的问题:
var type = p_variable.GetType().BaseType.GetGenericArguments()[0];
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3105 次 |
| 最近记录: |