简体   繁体   English

如何将对象强制转换为IList <T> T型未知

[英]How to cast a object to IList<T> with unknown type T


I have a object[] containig some values. 我有一个object[]包含一些值。 I want to extract infomation out of it, but I fail at casting the second object in the array (a WeakReference ) to a IList with T as the third value in the array. 我想从中提取信息,但是我将数组中的第二个对象( WeakReference )转换为IList,并将T作为数组中的第三个值。

Take a look at my code: 看看我的代码:

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

Any suggestions how I can cast the Target of the WeakReference to a IList interface with T = vals[3] ? 有关如何将WeakReference的Target转换为具有T = vals [3]的IList接口的任何建议?

It's really strange that you are packing so much heterogeneous information into an array . 将这么多异构信息打包到数组中真的很奇怪。 Arrays are normally used to store elements of the same type. 数组通常用于存储相同类型的元素。 Why not encapsulate the data in a proper type? 为什么不将数据封装成适当的类型?

But to answer the question as asked - in C# 4, you can use dynamic : 但要回答问题 - 在C#4中,你可以使用dynamic

var target = ((dynamic)vals[2]).Target;

if(target != null)
{
    object oo = Enumerable.ElementAt(target, vals[4]);
    //Do something with oo...
}

(EDIT: If you want to minimize the use of dynamic here, cast to a WeakReference and leave the dynamic call to the end. This way, type-safety is 'maximized'.) (编辑:如果你想在这里最小化dynamic的使用,转换为WeakReference并将动态调用留到最后。这样,类型安全性'最大化'。)

Otherwise, you can use reflection: 否则,您可以使用反射:

object target = ((WeakReference)vals[2]).Target;

if (target != null)
{
    object oo = target.GetType()
                      .GetProperty("Item")
                      .GetValue(target, new[] { vals[4] });
    //Do something with oo...
}

(EDIT: If the indexer could be explicitly implemented, you'll probably need to use the interface mappings.) (编辑:如果可以显式实现索引器,您可能需要使用接口映射。)

It was already suggested that you could use dynamic , but it sounds like you are also supposed to check that the object has the specified type. 已经建议你可以使用dynamic ,但听起来你也应该检查对象是否具有指定的类型。 I've also kept use of dynamic to a minimum: 我还将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;

If you just need the object from an enumerable, at a given index, here is a simple function that does it: 如果你只需要一个可枚举的对象,在给定的索引处,这是一个简单的函数:

    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();
    }

And in your case, you would do this: 在你的情况下,你会这样做:

        object oo = GetObjectAt((IEnumerable)(WeakReference)vals[2], (int)vals[4]);

Of course there are alternatives that look more sexy (see other answers), with fancy linq queries and cool C# 4 dynamic new trendy stuff :-) but, in general, if you don't "need" the T type (in your example code, you don't need it), you don't need generics. 当然有其他看起来更性感的选择(见其他答案),花哨的linq查询和酷C#4动态新时尚的东西:-)但是,一般来说,如果你不“需要”T型(在你的例子中)代码,你不需要它),你不需要泛型。 This solution is actually supported with any .NET Framework and C# versions, from 1 to 4. 任何.NET Framework和C#版本实际上都支持此解决方案,从1到4。

I think you're working too hard to be able to use the extension methods which don't seem to be necessary. 我认为你工作太辛苦了,无法使用似乎没有必要的扩展方法。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM