2011-04-24 65 views
3


我有object[]含有一些值。我想从中提取信息,但是我无法将数组中的第二个对象(一个WeakReference)投射到一个IList,并将T作为数组中的第三个值。
如何投射对象到IList <T>未知类型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的目标到IList接口与T =瓦尔斯[3]?

+0

为什么不简单地投射到“IList”? – 2011-04-24 12:42:53

+0

,因为我需要'ElementAt'方法,它只能用于IList alex 2011-04-24 12:44:45

+5

IList有Item属性,你可以做'list [(int)vals [4]]' – tvanfosson 2011-04-24 12:48:22

回答

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... 
} 

(编辑:如果日您可能需要使用接口映射。)

+0

''''' WeakReference'如果你知道对象是'WeakReference'? – tvanfosson 2011-04-24 12:58:21

+0

我试过这个,但是'.GetProperty(“Item”)'返回'null',如果这个属性是明确实现的并且是私有的。 – Timwi 2011-04-24 13:00:37

+0

@ tvanfosson:当然。然而,以后需要另一个'动态'演员阵容。 – Ani 2011-04-24 13:01:09

1

我认为您工作太辛苦,无法使用似乎没有必要的扩展方法。

object[] vals = GetValues(); 
var list = ((WeakReference)vals[2]).Target as IList; 
object oo = null; 
if (list != null) 
{ 
    oo = list[(int)vals[4]]; 
} 
+1

'IList '不*执行'IList'。 – Ani 2011-04-24 12:52:13

+0

@Ani - 但'List '确实实现了'IList',因此无论目标是否是强类型列表,它都应该工作。 – tvanfosson 2011-04-24 12:54:55

+0

当然,但是OP并没有说'IList '将会是'List '。顺便说一句,我不是downvoter。 – Ani 2011-04-24 12:58:14

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

如果只是需要将对象从一个枚举,给定的索引处,这里是一个简单的函数,它是:

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型(在你的示例代码中,你不需要它),你不需要泛型。该解决方案实际上支持从1到4的任何.NET Framework和C#版本。

+0

哈哈对我最好的答案西蒙你让我微笑。对于任何想要了解这种“老派”方式的人来说,这是一个很好的起点,那么你总是可以用Linq/Lambda等来构建它 – 2017-06-18 21:50:32

相关问题