En struct
Beschränkung auf Nullable<T>
ist IMHO wirklich unglücklich. Etwas wie ein Nullable<String>
o un Nullable<Nullable<Nullable<int>>>
mag verschwenderisch sein, aber was soll's? Verpacken Sie das Erstere als seinen Inhalt; entpacken Sie es als seinen Inhalt und setzen Sie die HasValue
wenn der Inhalt nicht null ist. Box die erste als eine int
wenn alle Nullables sich melden HasValue
und setzen Sie beim Auspacken HasValue
aller verschachtelten Elemente, wenn der Inhalt nicht null ist.
Andernfalls würde ich vorschlagen, dass Sie eine statische generische Klasse mit Typparameter erstellen T
die eine Delegateneigenschaft enthält, die eine T
als Parameter. Die Eigenschaft sollte den Inhalt eines privaten Feldes zurückgeben, das initialisiert werden sollte, um auf eine Methode zu verweisen, die den Typ von T
und setzen Sie den Delegaten entweder auf den struct
o class
Version, je nach Bedarf.
Hier ist ein Beispiel dafür, wovon ich spreche. In diesem Beispiel werden verschiedene Schnittstellenbeschränkungen anstelle von Struktur-/Klassenbeschränkungen verwendet, aber die gleichen Prinzipien können genauso effektiv eingesetzt werden.
static class \_FooDispatcher<T>
{
public static Action<T> Foo = setupFoo;
static void doFooWithIGoodFoo<TT>(TT param) where TT : IGoodFoo
{
Console.WriteLine("Dispatching as IGoodFoo with {1} type {0}", typeof(TT).ToString(), typeof(TT).IsValueType ? "value" : "reference");
param.Foo();
}
static void doFooWithIOkayFoo<TT>(TT param) where TT : IOkayFoo
{
Console.WriteLine("Dispatching as IOkayFoo with {1} type {0}", typeof(TT).ToString(), typeof(TT).IsValueType ? "value" : "reference");
param.Foo();
}
static void doFooSomehow<TT>(TT param)
{
Console.WriteLine("Nothing exciting with {1} type {0}", typeof(TT).ToString(), typeof(TT).IsValueType ? "value" : "reference");
}
static void setupFoo(T param)
{
System.Reflection.MethodInfo mi;
if (typeof(IGoodFoo).IsAssignableFrom(typeof(T)))
mi = typeof(\_FooDispatcher<T>).GetMethod("doFooWithIGoodFoo", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
else if (typeof(IOkayFoo).IsAssignableFrom(typeof(T)))
mi = typeof(\_FooDispatcher<T>).GetMethod("doFooWithIOkayFoo", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
else
mi = typeof(\_FooDispatcher<T>).GetMethod("doFooSomehow", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
Foo = (Action<T>)(@Delegate.CreateDelegate(typeof(Action<T>), mi.MakeGenericMethod(typeof(T))));
Foo(param);
}
}