处理多个“Is”语句的方法

时间:2013-06-10 16:31:07

标签: c# extension-methods

在我当前的代码中,我正在使用if/else if&测试对象的类型。 is

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is double)
        {
            //do something
        }
        else if (value is int)
        {
            //do something
        }
        else if (value is string)
        {
            //do something
        }
        else if (value is bool)
        {
            //do something
        }
       Type type = value.GetType();
       throw new InvalidOperationException("Unsupported type [" + type.Name + "]");
    }

我尝试使用Extension Method压缩所有else if语句,而不是使用is的长列表,而是无济于事。

以下是我对Extension Method

的尝试
public static class Extensions
    {
        public static bool Is<T>(this T t, params T[] values)
        {
            return values.Equals(t.GetType());
        }
    }

和方法:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is double)
        {
            //do something
        }
        else if (value.Is<object>(int, string, bool))
        {
            //do something
        }

        Type type = value.GetType();
        throw new InvalidOperationException("Unsupported type [" + type.Name + "]");
  }

有谁知道为什么会失败?任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:9)

您需要传递类型,而不是类名。您还应该使用Contains代替Equals

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

if(value.IsAny(typeof(SolidColorBrush), typeof(LinearGradientBrush), typeof(GradientBrush), typeof(RadialGradientBrush)))
{
}

Contains完全匹配该类型,因此您可能想要IsSubclassOfIsAssignableFrom

e.g

return types.Any(t => t.IsAssignableFrom(obj.GetType()));

答案 1 :(得分:4)

所以你在这里有几个问题。第一行是values.Equals(t.GetType())。您没有检查集合的每个值,而是检查集合整体是否等于一种类型。由于一个是object[],一个是Type,它们永远不会相等。您需要检查集合中 Any 的值是否等于类型。

接下来,您不希望参数是一堆对象,您希望它们是一堆类型。

这是一个更好的解决方案:

public static bool IsAny(this object obj, params Type[] types)
{
    return types.Any(type => type.IsAssignableFrom(obj.GetType()));
}

然后你会像:

一样使用它
bool b = "a".IsAny(typeof(int), typeof(double), typeof(MyClass));

答案 2 :(得分:1)

游戏后期,但如果你想保留通用语法并避免使用typeof,你可以创建一系列通用重载,其中包含越来越多的通用参数,达到一定的合理限制(只是比如Action<,,,>Func<,,,>做)

public static bool Is<T1, T2, T3, T4>(this object obj)
{
    return  obj is T1 ||
            obj is T2 ||
            obj is T3 ||
            obj is T4;
}

继续为T1TN的其他数字写入重载(其中N是您期望的最大数量。

您的用法如下:

else if (value.Is<SolidColorBrush, LinearGradientBrush, GradientBrush, RadialGradientBrush>())