Let's say I have a C# type :
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
).
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 ?
value = Foo<MyTypeString>(ref myTypeString, "Hello World") ;
Or even :
value = Foo(ref myTypeString, "Hello World") ;
???
P.S.: 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.
P.P.S.: 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.
Edit
As written above, I mixed both my Getter/Setter to ask this question, without realizing the problem was with the 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, i.e. C# 3.5) was :
Error CS0411: The type arguments for method `MyType.Get(ref T)' cannot be inferred from the usage. Try specifying the type arguments explicitly (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.
C# has Type inference in generics method so you can write just
value = Foo(ref myTypeString, "hello world");
using your current solution.
oxilumin is right, your current solution already works as you want. 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?
精彩评论