【问题标题】:Making a generic type for Tuples为元组创建一个泛型类型
【发布时间】:2011-06-13 14:36:09
【问题描述】:

我已经清楚地确定了如何在事先知道项目数的情况下制作通用元组如下...

        Type t = typeof(Tuple<,,>);
        Type[] keys = new Type[] { typeof(string), typeof(string), typeof(int) };
        Type specific = t.MakeGenericType(keys);

但是如果“keys”数组中的对象数量是可变的呢?你如何开始与初始分配“t”的球滚动?

干杯。 克雷格

【问题讨论】:

  • 如果我正确理解了这个问题,这可能会有所帮助:stackoverflow.com/questions/6268958/…
  • 很遗憾,.NET 类型系统不支持可变参数泛型类型,这才是您真正需要解决的一般问题。

标签: c# generics reflection tuples


【解决方案1】:

就我个人而言,我会有一个泛型类型定义的数组:

Type[] tupleTypes = {
    typeof(Tuple<>),
    typeof(Tuple<,>),
    typeof(Tuple<,,>),
    typeof(Tuple<,,,>),
    typeof(Tuple<,,,,>),
    typeof(Tuple<,,,,,>),
    typeof(Tuple<,,,,,,>),
    typeof(Tuple<,,,,,,,>),
};

可以在代码中执行此操作,但这会有点痛苦……可能类似于:

Type[] tupleTypes = Enumerable.Range(1, 8)
                              .Select(x => Type.GetType("System.Tuple`" + x)
                              .ToArray();

或者避开数组:

Type generic = Type.GetType("System.Tuple`" + keys.Length);
Type specific = generic.MakeGenericType(keys);

【讨论】:

  • 这是我目前的后备方案,但我希望有一种方法可以通过反射以编程方式选择具有正确数量的类型..感谢您的反馈!
  • 泛型类型的命名是标准的一部分,还是微软恰好在做的事情?类型是否保证被命名为“Tuple1”和“Tuple2”(带有反引号我不知道如何包含在评论中)?或者它会在 .NET 的未来版本中发生变化,或者如果使用其他框架实现,如 Mono?
  • @Darryl:命名是有保证的。例如,参见 ECMA 335 I.10.7.2。
【解决方案2】:

通过 Tuple.Create 构建 tupleTypes 的另一种方式:

// once
Type[] tupleTypes = typeof(Tuple).GetMethods(BindingFlags.Public | BindingFlags.Static)
    .Where(mi => mi.IsGenericMethod && mi.Name == "Create")
    .Select(mi => mi.ReturnType.GetGenericTypeDefinition())
    .Distinct() // make sure there is no duplicated return types
    .OrderBy(t => t.GetGenericArguments().Length)
    .ToArray(); // expect start from Tuple<>

// instant type creation
Type tupleType = tupleTypes[types.Length-1].MakeGenericType(types);

当然,这期望类 System.Tuple 将包含仅生成 Tuple<...> 的静态 Create 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-12
    • 1970-01-01
    • 2012-07-23
    • 1970-01-01
    • 2020-06-04
    • 1970-01-01
    相关资源
    最近更新 更多