不,没有这样的选择。
正如你提到的,对于:
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