English 中文(简体)
。 NET的思考:确定T阵列是否可转用于其他类型
原标题:.NET reflection: determining whether an array of T would be convertible to some other type
  • 时间:2009-10-30 14:56:58
  •  标签:

注 I m 不仅试图查明某些手工艺类型是否可使用电子计算机:

一、导言

    // is "toType" some sort of sequence that would be satisfied
    // by an array of type T? If so, what is the type of T?
    // e.g.
    // getArrayType(typeof(string[]) == typeof(string)
    // getArrayType(typeof(IEnumerable<int>)) == typeof(int)
    // getArrayType(typeof(List<string>)) == null // NOTE - Array<string> does not convert to List<string>
    // etc.
    private static Type getArrayType(Type toType)
    {
        if (toType.IsArray)
        {
            if (toType.GetArrayRank() != 1)
                return null;
            return toType.GetElementType();
        }
        // Look for IEnumerable<T>, and if so, return the type of T
        if (toType.IsGenericType && toType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
            return toType.GetGenericArguments()[0];

        return null;
    }

它能够更好处理更多案件? 例如,目前的情况

getType(typeof(ICollection<string>)) == null 

但扼杀可兑换成英磅

此外,我事先不知道“要素”类型是什么。

情况是:我撰写一份对描述性语言具有约束力的思考材料,如果你将物体[]传递给某种预期数字的方法(如果将输入阵列的每个要素转换到插图中的话),我想说的是“合理的工作”。

因此,我要澄清,我有某种方法签字:

void WriteCSV(ICollection<string> fields);

我的发言稿译员有一系列物体,它们都可能无意中显示:

object[] fields = new object[] { "one", 2, "three" };

然后,我的笔记译员需要指出,本案的真正需要是一系列的扼杀。

我要求我的译员放弃:

void WriteCSV(IRecord record);

<>7> 记录甚至可能实施一些可计量的电子数据:

interface IRecord : IEnumerable<string>
{
    void OtherMethods();
}

我无法从一系列东西中构筑《国际记录》。

因此,仅仅发现我需要的是哪类迷信。 页: 1 这里没有我?

最佳回答

可以通过创建一系列通用论点来做到这一点,并看它是否实施目标类型。 仅自array 以来,接口的密码检查确保只安装接口(IList, ICollection, IE amountable)。 此外,我还从实例中恢复阵列的类型(为了表明其明确性),在你们的法典中,你希望回到你所张贴的样本代码中的一般性论点。

private static Type GetArrayType(Type toType)
{
    if (toType.IsArray)
    {
        if (toType.GetArrayRank() != 1)
            return null;
        return toType;
    }

    // Verifies the type is generic and has only one generic argument
    if (toType.IsGenericType && toType.GetGenericArguments().Length == 1)
    {
        // Creates an array of the generic argument, e.g. IList<int> -> int[]
        var arrayOfType = toType.GetGenericArguments()[0].MakeArrayType();

        // Checks if the toType is an interface that the array implements
        if (arrayOfType.GetInterfaces().Contains(toType))
        {
            return arrayOfType    // arrayOfType.GetGenericArguments()[0];
        }
    }    
    return null;
}

public static void Test()
{
    Assert.AreEqual(typeof(int[]), GetArrayType(typeof(IList<int>)));
    Assert.AreEqual(typeof(int[]), GetArrayType(typeof(ICollection<int>)));
    Assert.AreEqual(typeof(int[]), GetArrayType(typeof(IEnumerable<int>)));

    Assert.IsNull(GetArrayType(typeof(List<int>)));
    Assert.IsNull(GetArrayType(typeof(Dictionary<int, string>)));
}

我希望它能够提供帮助。

问题回答

根据我在上个问题的回答:

您可使用该法典,以实施<代码>。 IE numberable<T> 在特定类型上接口,然后提取其通用参数。

Type type = typeof(ICollection<string>);

IEnumerable<Type> elementTypes = type.GetInterfaces()
    .Where(i => i.IsGenericType 
        && i.GetGenericTypeDefinition() == typeof(IEnumerable<>))
    .Select(i => i.GetGenericArguments()[0]);

例如,<代码>elementTypes将是一个包含System.String的单一要素。

你与要素类型做的是你们。 由于接口可以多次实施,因此你不妨修改询问,以获得单一执行。

Array case is covered by IEnumerable<T> as one dimensional arrays (the ones you are looking for using GetArrayrank)implement IList<T> which is in turn derived from IEnumerable<T>. It makes sense to look for IEnumerable next and treat element type as object - that is the way foreach construct treats collections.

还有一个需要考虑的事项是:供应类型执行<条码>、可计算和提炼;T> 数次(例如<条码>、可计算和提炼;object> 和<条码> ;string>。 例如,<代码>DataContractSerializer in this case doesn t consider the category as a Collection category.





相关问题
热门标签