我有object[]
包含一些值。我想从中提取信息,但是我无法将数组中的第二个对象(WeakReference
)转换为IList,其中T为数组中的第三个值。
看看我的代码:
object[] vals = GetValues(); //vals[2] = WeakReference, vals[3] = Type of T, vals[4] = index in the list
IList<((Type)vals[3])> list = (IList<((Type)vals[3])>)(((WeakReference)vals[2]).Target); //This line does not even compile, seems like I'm doing something wrong..
object oo = list.ElementAt((int)vals[4]);
//Do something with oo...
有关如何将WeakReference的Target转换为具有T = vals [3]的IList接口的任何建议吗?
答案 0 :(得分:4)
将非常多的异构信息打包到数组中真的很奇怪。数组通常用于存储相同类型的元素。为什么不将数据封装成适当的类型?
但要回答问题 - 在C#4中,您可以使用dynamic
:
var target = ((dynamic)vals[2]).Target;
if(target != null)
{
object oo = Enumerable.ElementAt(target, vals[4]);
//Do something with oo...
}
(编辑:如果你想在这里尽量减少dynamic
的使用,请转换为WeakReference
并将动态调用留到最后。这样,类型安全就是'最大化'。)
否则,您可以使用反射:
object target = ((WeakReference)vals[2]).Target;
if (target != null)
{
object oo = target.GetType()
.GetProperty("Item")
.GetValue(target, new[] { vals[4] });
//Do something with oo...
}
(编辑:如果可以显式实现索引器,则可能需要使用接口映射。)
答案 1 :(得分:2)
已经建议你可以使用dynamic
,但听起来你也应该检查对象是否具有指定的类型。我还一直使用dynamic
:
object target = ((WeakReference) vals[2]).Target;
if (target == null)
throw new InvalidOperationException("Target cannot be null.");
object result = Enumerable.ElementAt((dynamic) target, (int) vals[4]);
if (result != null && !((Type) vals[3]).IsAssignableFrom(result.GetType()))
throw new InvalidOperationException(string.Format("The retrieved object is a {0}, but the expected type was {1}.", result.GetType(), (Type) vals[3]));
return result;
答案 2 :(得分:2)
如果你只需要一个可枚举的对象,在给定的索引处,这是一个简单的函数:
public static object GetObjectAt(IEnumerable enumerable, int index)
{
int i = 0;
foreach (object obj in enumerable)
{
if (i == index)
return obj;
i++;
}
throw new IndexOutOfRangeException();
}
在你的情况下,你会这样做:
object oo = GetObjectAt((IEnumerable)(WeakReference)vals[2], (int)vals[4]);
当然有些替代品看起来更性感(参见其他答案),花哨的linq查询和酷炫的C#4动态新潮流的东西:-)但是,一般来说,如果你不“需要”T型(在您的示例代码中,您不需要它),您不需要泛型。任何.NET Framework和C#版本实际上都支持此解决方案,从1到4。
答案 3 :(得分:1)
我认为你工作太辛苦了,无法使用似乎没有必要的扩展方法。
object[] vals = GetValues();
var list = ((WeakReference)vals[2]).Target as IList;
object oo = null;
if (list != null)
{
oo = list[(int)vals[4]];
}