The way to handle multiple "Is" statements

In my current code, I'm testing the type of an object with if/else if and 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 + "]"); } 

Instead of having a long list of else if , I tried to condense all the is statements using the Extension Method , but to no avail.

Here is my attempt in the Extension Method :

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

and method:

 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 + "]"); } 

Does anyone know why this fails? Any help would be greatly appreciated!

+4
source share
3 answers

You need to pass types to it, not class names. You should also use Contains instead of 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 exactly matches the type, so you might need IsSubclassOf or IsAssignableFrom instead

eg

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

So you have a few problems. The first of these is the line: values.Equals(t.GetType()) . You do not check each of the values ​​of the collection; you check whether the collection as a whole matches one type. Since one is object[] and one is Type , they will never be equal. You need to check if any of the values ​​in the collection match the type.

Then you do not want the parameters to be an object association, you want them to be a type association.

Here is the best solution:

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

Then you will use it like:

 bool b = "a".IsAny(typeof(int), typeof(double), typeof(MyClass)); 
+4
source

Late to the game, but if you want to keep the general syntax and avoid using typeof , you can create a series of general overloads with the number of common parameters increased to some reasonable limit (just like Action<,,,> and Func<,,,> do)

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

And move on to writing overloads for other numbers T1 through TN (where N is the maximum number you expect.

Then your use is as follows:

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

Source: https://habr.com/ru/post/1485477/


All Articles