【问题标题】:Approach for using 'params' in a generic type definition在泛型类型定义中使用“参数”的方法
【发布时间】:2009-07-28 16:16:35
【问题描述】:

This question 让我思考如何编写一个需要包含类型参数变量列表的方法。

一种方法是接受params Type[] 作为参数的一部分,例如:

public static bool IsOneOf(this object obj, params Type[] types)
{
    return types.Contains(obj.GetType());
}

但是,使用有点冗长(例如obj.IsOneOf(typeof(int), typeof(bool), typeof(double))),我想知道定义一种采用任意数量通用参数的方法的替代方法。类似于:

public static bool IsOneOf<params TArgs[]>(this object obj)
{
    // use TArgs here
}

对此的一种解决方案是使用 4.0 BCL 的 Tuple 类(它定义了一个公共接口 ITuple 以及 Tuple&lt;T1&gt;Tuple&lt;T1, T2&gt; 等)来定义如下内容:

public static bool IsOneOf<TTypes>(this object obj) where TTypes : ITuple
{
    Type tupleType = typeof(TTypes);
    return tupleType.GetGenericArguments().Contains(obj.GetType());
}

然后可以这样使用:

if (obj.IsOneOf<Tuple<int, bool, decimal>>()) { ... }

这里是否有性能方面的考虑,或者是否有替代方法来实现这种语法?

【问题讨论】:

  • .net 框架中是否已经有一些东西可以检查列表中是否存在项目?除了对对象进行扩展之外,您这样做的目的是什么?
  • 是的,有 List.Contains。问题是您不能在方法的通用参数定义中包含params。最初的目的是对对象的扩展,但它可能适用于其他地方。

标签: c# generics extension-methods


【解决方案1】:

您可以通过将循环展开到每个“arity”的特殊情况来挤出一点额外的速度:

static bool IsOneOf<T1>(object o)
{
    return (o.GetType() == typeof (T1));
}

static bool IsOneOf<T1, T2>(object o)
{
    return (o.GetType() == typeof(T1)) ||
           (o.GetType() == typeof(T2));
}

static bool IsOneOf<T1, T2, T3>(object o)
{
    return (o.GetType() == typeof(T1)) ||
           (o.GetType() == typeof(T2)) ||
           (o.GetType() == typeof(T3));
}

等等。

但是,您需要多久知道一个对象是一对不相关类型中的一个?更别说三个或更多。对我来说似乎是一个非常模糊的需求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多