不,沒有這樣的選擇。
正如你提到的,對於:
public T this[] { get; set; }
你需要一些「通用性」,在外部範圍,爲this[]
也無法對自己的通用。所以,你的課/不管是generic-<T>
,並強制用戶不僅要指定T,而且要爲所有元素指定一個T。
對於Dictionary<string, Tuple<Type, object>>
,你可以有最好的是:
public object this[] { get; set; }
public IMyInterface this[] { get; set; }
這是因爲在編譯的時候,你的整個字典類沒有對項目類型的任何信息。該代碼限於object
,如Typle<Type,object>
。你唯一能做的就是返回一個object
,或者嘗試將它轉換成其他已知類型,比如接口。
如果從使用this[]
辭職,你可以嘗試做一個「聰明的getter」:
public TValue GetItem<TValue>(TKey index) { ... }
public void SetItem<TValue>(TKey index, TValue value) { ... }
這將只是做所有的鑄件(return (TValue)tuple.Item2
等)。但是,當「TValue」未知時,在上下文中使用時會出現一些問題,例如使用困難。所以,你也可能需要
public object GetItem(TKey index) { ... }
public void SetItem(TKey index, object value) { ... }
只是爲了避免繁瑣的GetItem<object>
。當然,無論使用哪種TValue版本,用戶都需要明確地指定TValue(除了SetValue可能推斷的地方,不一定正確)。
現在,讓我們回到基礎。你有什麼想法
public T this[] { get; set; }
anyways,hm?當你將Tuple中的Type和Object捆綁在一起時,你似乎希望能夠在Dictionary中包裝一個異源項目,對嗎?那麼,告訴我,如何最終用戶和/或代碼/編譯器將如何能夠猜到正在返回wnat:
var foo = myDictionary["bar"];
這將是foo
變量的類型?編譯器無法猜測,因爲在編譯時myDictionary只知道它會保存一些Tuple<Type,object>
,但它現在不包含任何東西。此外,它實際上還沒有存在,因爲它正在被編譯。根據你的Tuple
的確切類型強制「返回值」是不可能的。
此外,爲什麼你甚至會在該元組中攜帶Type?保存在字典中的object
總是知道它的類型。你不需要攜帶類型,你可以簡單地在該對象上使用.GetType()
,但效果相同。如果你想保留上傳的類型信息(例如:有一個Bar從Foo繼承下來,upcast Bar作爲Foo並放入magiccontainer中,然後作爲Foo not Bar取回),那麼你的運氣有點不足。沒有幫助,並會返回你「動態對象」,這將知道自己是「酒吧」,並允許您動態調用所有酒吧方法。我認爲攜帶這種類型是完全沒有必要的,除非你有一些強大的屏蔽/隔離要求 - 但在這種情況下,簡單的「攜帶類型並鑄造」根本不會幫助。對於這樣的事情,你可能需要動態代理。由於我已經有了健談,最後(有點沒用,但你可能還是想聽到它)注意:實際上可以強制一個「強制類型」轉換爲存儲在「類型」中的類型。你可以用表達式來做到這一點。您可以動態構建Expression<>
,將其與正確的Type對象綁定並調用。從https://stackoverflow.com/a/3983342/717732
借款代碼它看起來像:
public static ???? castAndReturn(object item, Type type)
{
var p = Expression.Parameter(typeof(object), "i");
var c = Expression.Convert(p, type);
var ex = Expression.Lambda<Func<object, ????>>(c, p).Compile();
return ex(item);
}
但同樣,有什麼返回類型你投入????
佔位符,嗯?唯一的可能性是object
,dynamic
,或者定製的衆所周知的通用基礎類型。回到原點。 D'哦。抱歉。沒有,真的,方式。
你能表現出更多的周邊代碼來獲得完整的圖片? – 2014-10-20 13:52:02
只是爲了檢查,你有沒有考慮過ExpandoObject? – 2014-10-20 13:59:47
@manuFS:我沒有,但我有清楚的感覺,我會遇到與'dynamic'一樣的問題。例如,我看到ExpandoObject實現了IDynamicMetaObjectProvider,它是。只有NET 4,所以很可能會有同樣的問題。 – user1846231 2014-10-20 14:14:16