Generics 在构造函数参数中激活具有泛型数组的泛型类型时出现问题

Generics 在构造函数参数中激活具有泛型数组的泛型类型时出现问题,generics,reflection,activator,Generics,Reflection,Activator,我对以下代码有一个非常奇怪的问题: using System; using System.Linq; namespace ConsoleApp1 { public class Program { public static void Main(string[] args) { var testTuples1 = GimeStringTuples("foo", "bar"); var testTupl

我对以下代码有一个非常奇怪的问题:

using System;
using System.Linq;

namespace ConsoleApp1
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var testTuples1 = GimeStringTuples("foo", "bar");
            var testTuples2 = GimeTuples("foo", "bar");
            Console.ReadKey();
        }

        public static object GimeStringTuples(params string[] values)
        {
            Type genericType = Type.GetType("System.Tuple`" + values.Length);
            Type[] typeArgs = values.Select(_ => typeof(string)).ToArray();
            Type specificType = genericType.MakeGenericType(typeArgs);
            return Activator.CreateInstance(specificType, values);
        }

        public static object GimeTuples<T>(params T[] values)
        {
            Type genericType = Type.GetType("System.Tuple`" + values.Length);
            Type[] typeArgs = values.Select(_ => typeof(T)).ToArray();
            Type specificType = genericType.MakeGenericType(typeArgs);

            dynamic result;
            string[] testArgs = { "foo", "bar" };
            result = Activator.CreateInstance(specificType, testArgs);
            result = Activator.CreateInstance(specificType, values);
            return result;
        }
    }
}
这很奇怪,因为它基本上与它前面执行的行相同:

result = Activator.CreateInstance(specificType, testArgs);
在这两种情况下,相同的参数作为
specificType
参数传递,而
字符串[2]
作为第二个参数传递

而且
GimeStringTuples
方法工作得很好。。。虽然没有涉及泛型-这可能是暗示


有人能解释这种不寻常的行为吗

我可以告诉你发生了什么。查看生成的程序集后,您可以看到编译器引入了一个
对象[]
包装
参数:

Activator.CreateInstance(specificType, new string[] { "foo", "bar" });
Activator.CreateInstance(specificType, new object[] { values });
现在无法再找到正确的重载。 如果添加强制转换,您将获得预期结果,代码将再次工作:

Activator.CreateInstance(specificType, values as string[])
但我无法告诉您为什么会发生这种情况,也许可以从规范中删除。

好的,因此解决方案(感谢@thehenny):

使用系统;
使用System.Linq;
名称空间控制台EAPP1
{
公共课程
{
公共静态void Main(字符串[]args)
{
var testTuple=GimeTuples(“foo”、“bar”);
Console.WriteLine(testTuple);
Console.ReadKey();
}
公共静态对象GimeTuples(参数T[]值)
{
Type genericType=Type.GetType(“System.Tuple`”+values.Length);
Type[]typeArgs=values.Select(=>typeof(T)).ToArray();
类型specificType=genericType.MakeGenericType(typeArgs);
object[]constructorArguments=values.Cast().ToArray();
返回Activator.CreateInstance(specificType、constructorArguments);
}
}
}

这迫使编译器将泛型数组元素作为参数传递,而不是将整个数组作为单个参数传递。

谢谢@thehenny。。。这就足够我继续下去了。可以通过首先将值数组强制转换为对象[]来避免这种情况。这似乎是编译器在将泛型数组作为参数传递给具有params签名的方法时如何处理泛型数组的微妙之处。。。它作为单个参数传递整个数组,而不是传递数组的每个元素。奇怪的
Activator.CreateInstance(specificType, values as string[])
using System;
using System.Linq;

namespace ConsoleApp1
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var testTuple = GimeTuples("foo", "bar");
            Console.WriteLine(testTuple);
            Console.ReadKey();
        }

        public static object GimeTuples<T>(params T[] values)
        {
            Type genericType = Type.GetType("System.Tuple`" + values.Length);
            Type[] typeArgs = values.Select(_ => typeof(T)).ToArray();
            Type specificType = genericType.MakeGenericType(typeArgs);
            object[] constructorArguments = values.Cast<object>().ToArray();
            return Activator.CreateInstance(specificType, constructorArguments);
        }
    }
}