我有一个班级
public class A<T>
{
public static string B(T obj)
{
return TransformThisObjectToAString(obj);
}
}
上面使用字符串纯粹是示范性的。我可以在已知/指定的类型上调用这样的静态函数:
string s= A<KnownType>.B(objectOfKnownType);
如果我事先不知道 T ,我该怎么做这个电话,而是我有一个类型为 Type 的变量。如果我这样做:
Type t= typeof(string);
string s= A<t>.B(someStringObject);
我收到此编译器错误:
Cannot implicitly convert type 't' to 'object'
答案 0 :(得分:26)
您无法直接执行此操作,但可以使用反射在运行时提供类的类型参数。我没有测试过这个,但是这样的事情应该有效:
// We want to do something like this:
// object o = "Hello"
// Type t = o.GetType();
//
// This is pseudo-code only:
// string s = A<t>.B(o);
string InvokeA(object o) {
// Specify the type parameter of the A<> type
Type genericType = typeof(A<>).MakeGenericType(new Type[] { o.GetType() });
// Get the 'B' method and invoke it:
object res = genericType.GetMethod("B").Invoke(new object[] { o });
// Convert the result to string & return it
return (string)res;
}
当然,问题是这是否真的是你需要的 - 如果你对作为参数给出的对象一无所知,你也可以用对象编写整个代码。但是,我可以想象一些有用的场景,所以我想你可以尝试使用它。
答案 1 :(得分:11)
你做不到。必须在编译时知道泛型类型标识符。
修改强>
从其他帖子开始,似乎可以通过动态生成方法并调用它 - 当然这有危险。有关更多信息,请参阅Thomas'和Dathan的帖子。
答案 2 :(得分:9)
在框架和CLR中绝对支持这一点 - 只是在C#中不优雅。但是,在辅助方法的帮助下,你可以完成我认为你想要的东西:
public class A<T>
{
public static string B(T obj)
{
return obj.ToString();
}
}
public class MyClass
{
public static void DoExample()
{
Console.WriteLine(ExecuteB("Hi"));
Console.WriteLine(ExecuteB(DateTime.Now));
}
public static object ExecuteB(object arg)
{
Type arg_type = arg.GetType();
Type class_type = typeof(MyClass);
MethodInfo mi = class_type.GetMethod("ExecuteBGeneric", BindingFlags.Static | BindingFlags.Public);
MethodInfo mi2 = mi.MakeGenericMethod(new Type[] { arg_type });
return mi2.Invoke(null, new object[] { arg });
}
public static object ExecuteBGeneric<T>(T arg)
{
return A<T>.B(arg);
}
答案 3 :(得分:1)
你做不到。但是你提出的问题是错误的问题。在这种情况下(如99%的情况),您实际需要的只是类型约束。
尝试:
public class A<T> where T : object
或者,如果T是已知类,子类或接口,那么最好使用
public class A<T> where T : YourAbstractClass
还存在其他类型约束。更多详情:http://msdn.microsoft.com/en-us/library/d5x73970(VS.80).aspx
总的来说,在学习一门新语言时,你经常需要广泛地思考你想要实现的内容,而不是专门找到你想要做什么的内容。这很像现实世界的口头语言。通过阅读字典学习德语并将单词强制用于英语语法,或者学习语法并学习单词来学习德语之间的区别。是的,一个德语发言者会理解一个在词典中发言的人,但每个句子的WTF会更高。
答案 4 :(得分:0)
尝试在运行时替换type参数会破坏类型saftey的整个目的,这是由C#compiler强制执行的.C#编译器确保在编译时指定了类型参数,并且在运行时类型参数没有歧义。怀疑你可以在Generic Type中运行时替换类型参数。类型为“ Type ”的类型参数类似于具有未绑定的泛型类型。
答案 5 :(得分:0)
我根据这里的一些答案创建了这个帮助方法,而不是在网络上。
用法:
var unzipExtractor = unzip.Extract({ path: dir });
var source = fs.createReadStream(dir + 'sub.zip');
var unZip = source.pipe(unzipExtractor);
unZip.on('error', function(err) {
fs.unlink(dir + 'sub.zip', function(err){
if (err) console.log(err); else console.log('File extracted !');
})
})
方法:
InvokeGenericMethodWithRuntimeGenericArguments( MyMethodWithGenericType<IType>, new[] {MyRuntimeGenericType}, null);