none
Generic extension methods (T and T[ ]) RRS feed

  • Question

  • Is is possible to condense these three extension methods (they don't have to be extension methods) with generics?

    public static class ValueExtensions
    {
            
            
            public static bool Equals(this double myDouble, double compareValue)
            {
    
                return false;
            }
    
            public static bool Equals(this double myDouble, double[] compareValue)
            {
    
                return false;
            }
    
            public static bool Equals(this double[] myDouble, double[] compareValue)
            {
    
                return false;
            }
    
    
    
        }
     

    The problem I run into with the below code is when I try to iterate a double[].
     public
    
    static
    bool
    Equals(this
    T myValue, T compareValue)
    {

    return
    false
    ;
    }


    Friday, January 29, 2010 10:26 PM

All replies

  • Do you mean:
        public static void Test2<T>(this T a, T b) {}
        public static void Test2<T>(this T a, T[] arr) {}

    -Karel

    Friday, January 29, 2010 11:37 PM
    Moderator
  • Hi,fixitchirs:

        Thanks for posting on our forum. Could you provide some more elaboration for others to understand your questions better.


    Please mark the right answer at right time.
    Thanks,
    Sam

    Friday, February 5, 2010 6:47 AM
  • Sorry, I was away this week.  I will try to put an example together today or over the weekend.

    chris
    Friday, February 5, 2010 1:22 PM
  • What I want to do is include extension methods such as : In, LessThan, GreaterThan for String, String[], double, double[].  meaning compare a string to string / string to string[] / string[] to string[] / string[] to string (same goes for double).

    The way I'm doing this now looks like I will need 4 separate methods for each comparison method.  Is there a different way?

    public class Program
        {
            static void Main(string[] args)
            {
                bool isInArray = false;
                
                double a = 7f;
    
                double[] doubleValues = { 1, 2, 3, 4, 5, 6, 7 };
                double doubleValue = 2;
                isInArray = a.In(doubleValues);
                isInArray = a.In(doubleValue);
    
                string b = "a";
                string[] stringValues = { "a", "b", "c" };
                string stringValue = "a";
    
                isInArray =  b.In(stringValues);
                isInArray = b.In(stringValue);
    
                double[] c = { 1, 2, 3};
                double d = 1;
                isInArray = c.In(doubleValues);
                isInArray = c.In(d);
    
                isInArray = stringValues.In(stringValues);
                isInArray = stringValues.In(stringValue);
            }
        }
    
        public static class Extensions
        {
            //http://grabbagoft.blogspot.com/2007/07/constrained-generic-extension-methods.html
    
    
            public static bool In<T>(this T myValue, IEquatable<T> compareValue) //where T : IEquatable<T>
            {
                if (compareValue.Equals(myValue))
                    return true;
    
                return false;
            }
    
            public static bool In<T>(this T myValue, IEnumerable<T> compareValue) //where T: IEquatable<T>
            {
                foreach (T item in compareValue)
                {
                    if (item.Equals(myValue))
                        return true;
                }
    
                return false;
            }
    
            public static bool In<T>(this IEnumerable<T> myValue, IEnumerable<T> compareValue) //where T: IEquatable<T>
            {
                bool flag = true;
                
                using (IEnumerator<T> enumerator = myValue.GetEnumerator())
                {
                    while (enumerator.MoveNext())
                    {
                        if (!enumerator.Current.In(compareValue))
                            flag = false;
                    }
                }
                return flag;
            }
    
            public static bool In<T>(this IEnumerable<T> myValue, T compareValue) //where T: IEquatable<T>
            {
                using (IEnumerator<T> enumerator = myValue.GetEnumerator())
                {
                    while (enumerator.MoveNext())
                    {
                        if (!enumerator.Current.Equals(compareValue))
                            return true;
                    }
                }
                return false;
            }
        }

    Monday, February 8, 2010 9:24 PM
  • Dang, currently most of my code is boxed like so:

    object ob = (double)2;
    
    object oc = (double[]) new double[] { 1, 2, 3, 4 };
    
    ob.In(oc);
    So the extension methods won't really work... any advice?

    Monday, February 8, 2010 9:50 PM
  • It's generally best to keep as much type safety as possible (and that means using "object" as little as possible).

    If you can't change the rest of the code, then you can add a static method like Equals that takes two objects and branches according to their type:
      public static bool Equals(object a, object b)
      {
        if (a is double && b is double)
          ...;
        else if ...
        else
          throw ...;
      }

    Of course, this kind of code violates an OOP principle (via its "switch" statement based on the object's type) and also adds a category of bugs that can be detected only at runtime instead of compiletime. This is par for the course when other parts of the code doesn't support type safety.

    You could make it an extension method, but I don't recommend it.

           -Steve
    Programming blog: http://nitoprograms.blogspot.com/
      Including my TCP/IP .NET Sockets FAQ
    Microsoft Certified Professional Developer

    How to get to Heaven according to the Bible
    Tuesday, February 9, 2010 2:22 PM
  • I agree that the non typed code will have to be looked at.  I'm actually rewriting this parser to support non-algebraic grammar so for now I changed the InnerEvaluate methods to return object instead of double.  I will try again to support generics.


    Tuesday, February 9, 2010 2:43 PM
  • In the below code, do I have to make 'StringExpression' class a generic to be able to return '_variable' with 'InnerEvaluate<T>'  ?

    public sealed class StringExpression : Expression
        {
            private string _variable;
    
            
            protected override T InnerEvaluate<T>(ExpressionContext context)
            {
                //return _variable.ToString(); <-------
                return default(T);
            }
    
            protected override object InnerEvaluate(ExpressionContext context)
            {
                return _variable.ToString();
            }
        }
    UPDATE: I think I got it.
    return (T)Convert.ChangeType(_variable, typeof(T));

    Tuesday, February 9, 2010 3:02 PM
  • I didn't know this... I created a generic method : SomeMethod<T>(params T[] arguments) and I can call it SomeMethod(someVariable) without specifying the Type for T. That is way cool.

    update:  is there a way to call the non-generic method explicitly?

    Also, what happens when a generic type is converted to Object?
    Tuesday, February 9, 2010 3:48 PM