Wie Jared sagt, können Sie es im Code genauso angeben, wie Sie es bei einem statischen Aufruf tun würden:
using System;
class Program {
void Foo<T>() {
Console.WriteLine(typeof(T));
}
static void Main(string[] args) {
dynamic p = new Program();
p.Foo<string>();
}
}
Der obige Code druckt System.String
.
Wenn Sie jetzt nur wüssten T
で Ausführung Zeit, ist es etwas schwieriger. Wenn Sie jedoch eine Instanz davon haben, können Sie dynamische Typisierung und Typinferenz zusammen verwenden:
using System;
class Program {
void Foo<T>() {
Console.WriteLine(typeof(T));
}
static void Main(string[] args) {
dynamic p = new Program();
dynamic v = GetRandomInstance();
// Now to call p.Foo<T> where T is the type of v's value...
Dummy(v, p);
}
static void Dummy<T>(T t, Program p) {
p.Foo<T>();
}
static object GetRandomInstance() {
return DateTime.Now.Hour > 10 ? "hello" : (object) 10;
}
}
EDIT: Pavel hat in den Kommentaren eine tolle Idee geäußert. Sie müssen nicht mit einer Instanz von T
nur ein Array. Das bedeutet, dass Sie sogar Typargumente verwenden können, bei denen das normalerweise nicht möglich ist bekommen. eine Instanz von T
(z.B. durch einen privaten Konstruktor):
using System;
class PrivateConstructor {
private PrivateConstructor() {}
}
class Program {
static void Foo<T>() {
Console.WriteLine(typeof(T));
}
static void CallFooProxy<T>(T[] array) {
Foo<T>();
}
static void CallFoo(Type t) {
dynamic array = Array.CreateInstance(t, 0);
CallFooProxy(array);
}
static void Main(string[] args) {
CallFoo(typeof(PrivateConstructor));
}
}
Bevor jemand fragt - nein, damit kann man nicht anrufen Foo<Enumerable>
dynamisch - Sie können eine statische Klasse immer noch nicht als Typargument verwenden, auch wenn Sie versuchen, den Versuch bis zur Ausführungszeit zu verzögern :)
Wenn all das aus irgendeinem Grund fehlschlägt, geht es wieder zurück zur normalen Reflexion... die Methodeninformationen abrufen, die MakeGenericMethod
und rufen sie auf.