Specialize implementation of GenericType<A,B> for case A == B?
I have a generic class which takes two type parameters, Generic<A, B>
. This class has methods with signatures that are distinct so long and A
and B
are distinct. However, if A == B
the signatures match exactly and overload resolution cannot be performed. Is it possible to somehow specify a specialisation of the method for this case? Or force the compiler to arbitrarily choose one of the matching overloads?
using System;
namespace Test
{
class Generic<A, B>
{
public string Method(A a, B b)
{
return a.ToString() + b.ToString();
}
public string Method(B b, A a)
{
return b.ToString() + a.ToString();
}
}
class Program
{
static void Main(string[] args)
{
Generic<int, double> t1 = new Generic<int, double>();
Console.WriteLine(t1.Method(1.23, 1));
Generic<int, int> t2 = new Generic<int, int>();
// Following line gives:
// The call is ambiguous between the following methods
// or properties: 'Test.Generic<A,B>.Method(A, B)' and
// 'Test.Generic<A,B>.Method(B, A)'
Console.WriteLine(t2.Method(1, 2));
}
}
}
Given the purely generic definition there is no way to force the compiler to choose an overload. It has no way to distinguish a winner between the two methods.
It may seem a good idea to just pick one or the other but the decision needs to be deterministic. Even something as simple as the first one in the file is not really doable because you must consider partial classes. How would the compiler choose the first method if each were in a different file?
What you can do though is add a non-generic version of the method which accepts int. The compiler will choose the non-generic version over the generic version and it will produce a win in this very limited scenario. You would have to repeat that for every type which may have a conflict though.
For example. Adding this method will solve your compilation error, but only for int.
public string Method(int b, int a)
{
return b.ToString() + a.ToString();
}
感谢好的答案,他们促使我进入这个解决方案:
using System;
namespace Test
{
class Generic<A, B>
{
public string Method(A a, B b)
{
return this.DefaultMethod(a, b);
}
protected string DefaultMethod(A a, B b)
{
return a.ToString() + b.ToString();
}
public string Method(B b, A a)
{
return b.ToString() + a.ToString();
}
}
class Generic<A> : Generic<A, A>
{
public new string Method(A a, A b)
{
return base.DefaultMethod(a, b);
}
}
class Program
{
static void Main(string[] args)
{
Generic<int, double> t1 = new Generic<int, double>();
Console.WriteLine(t1.Method(1.23, 1));
Generic<int> t2 = new Generic<int>();
Console.WriteLine(t2.Method(1, 2));
}
}
}
I know it kind of defeats the purpose of the generic, but what about defining the method once, taking two parameters of type object
?
Inside the method, you can examine the types and work out which one of your two options to call.
namespace Test
{
class Generic<A, B>
{
public string Method(object a, object b)
{
if (a is A && b is B)
return MethodOneTwo;
else if (a is B && b is A)
return MethodTwoOne;
else
throw new ArgumentException("Invalid Types");
}
private string MethodOneTwo(A a, B b)
{
return a.ToString() + b.ToString();
}
private string MethodTwoOne(B b, A a)
{
return b.ToString() + a.ToString();
}
}
}
链接地址: http://www.djcxy.com/p/57840.html
上一篇: 在运行时获取通用类的类