web analytics

Working with C# Generics

Options
@2021-04-13 20:09:03

Overloading Generic Methods

Generic methods can be overloaded. In the following code, The generic method MethodA is overloaded by a nongeneric method:

using System;

namespace GenericMethod
{
    public class MyClass
    {
        public void MethodA<T>(T arg)
        {
            Console.WriteLine("MyClass.MethodA<T>(T arg)");
        }

        public void MethodA(int arg)
        {
            Console.WriteLine("MyClass.MethodA(int arg)");
        }
    }

    public class Program
    {
        public static void Main()
        {

            MyClass obj = new MyClass();

            obj.MethodA(5);

        }
    }
}

Interestingly, guess what result is outputted when the following statements  is execute?

MyClass obj = new MyClass();
obj.MethodA(5);

It is

MyClass.MethodA<T>(T arg)

Or

MyClass.MethodA(int arg)

It seems that both the generic method and the nongeneric method match the call, but which method will be executed exactly? Compile the code and run, the answer is:

MyClass.MethodA(int arg)

Why, it is because that when generic methods can overload nongeneric methods, if the combination of a generic and nongeneric method is ambiguous, the nongeneric method is called. The compiler prefers nongeneric methods over generic methods of the same signature.

@2021-04-13 21:09:44

Avoiding ambiguous Method Overloading When Defining a Generic Class

When define your own custom generic class, you should pay attention to if any ambiguous method overloading is defined. Let’s take a look the following example where methodA is overloaded:

public class MyClass<T, U>
{
    public void MethodA(T arg)
    {
        Console.WriteLine("MyClass.MethodA(T arg)");
    }
    public void MethodA(U arg)
    {
        Console.WriteLine("MyClass.MethodA(U arg)");
    }

    public void MethodA()
    {
        Console.WriteLine("MyClass.MethodA()");
    }
}

Both functions have a single type parameter. The type parameters are different.  Everything looks OK, right?  In the example blow, a Myclass variable is declared with both type parameters are integer, then the MethodA is called:

public class Program
{
   public static void Main()
   {
 
       MyClass<int, int> obj = new MyClass<int, int>();
 
       obj.MethodA(5);
 
   }
}

When you try to compile the above code in Visual Studio, the following compilation error is shown:

The call is ambiguous between the following methods or properties: 'GenericMethod.MyClass<T,U>.MethodA(T)' and 'GenericMethod.MyClass<T,U>.MethodA(U)'

Why?  This is because that although the type parameters in bother methods are different, each parameter could be anything, including both parameters being identical. This makes certain renditions of MethodA ambiguous. For example, they both have a single integer parameter in the above example. In this ambiguous  situation, a compile error is manifested when the method is called.

If you comment the following code in the previous example:

public class Program
{
   public static void Main()
   {
 
       MyClass<int, int> obj = new MyClass<int, int>();
 
       //obj.MethodA(5);
 
   }
}

Then you can compile the code!

The above error reminds us that we have to test every permutation of type parameters to predict and avoid potential ambiguousness for clients of a library.

A simple fix to the above problem could be just using different method names, see the code below:

public class MyClass<T, U>
{
    public void MethodA(T arg)
    {
        Console.WriteLine("MyClass.MethodA(T arg)");
    }
    public void MethodB(U arg)
    {
        Console.WriteLine("MyClass.MethodB(B arg)");
    }

    public void MethodA()
    {
        Console.WriteLine("MyClass.MethodA()");
    }
}

Comments

You must Sign In to comment on this topic.


© 2024 Digcode.com