對Nullable<T>
的struct
約束是恕我直言,真的很不幸。像Nullable<String>
或Nullable<Nullable<Nullable<int>>>
可能會浪費,但那又如何?將前者作爲其內容;將其作爲內容取消裝箱,如果內容非空,則設置HasValue
。將前者作爲int
,如果所有可空白報告爲HasValue
,並且拆箱時,如果內容非空,則設置所有嵌套項目的HasValue
。
否則,我建議您創建一個類型參數爲T
的靜態泛型類,該靜態泛型類包含一個接受T
作爲參數的委託屬性。該屬性應該返回應該初始化的私有字段的內容,以指向將檢查T
類型的方法,並根據需要將代理設置爲struct
或class
版本。
下面是我正在談論的一個示例;這個使用了各種接口約束而不是結構/類約束,但是同樣的原則可以被有效地使用。
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);
}
}
出於興趣,您的實際用例試圖做什麼樣的事情? – AakashM 2012-03-08 15:51:06
@AakashM:簡單,我需要以不可空的值類型以不同的方式轉換可空類型。我認爲一個通用的重載是解決它的一個快速方法。該方法需要一個對象和一個類型參數,我不能限制類型參數(嗯,我可以,但我不能超載它)。 – Abel 2012-03-08 19:16:01