Проблема с перегрузкой универсального метода - PullRequest
2 голосов
/ 23 мая 2011

У меня есть следующие методы:

void s<t>(int a, t b)
{
    ...
    ..
    .
}

void s<int>(int a, int b)
{
    ...
    ..
    .
}

void s<long>(int a, long b)
{
    ...
    ..
    .
}

когда я хочу использовать его как s<long>(10,10), я вижу эти переопределения во всплывающей подсказке. s<long>(int a,int b); и s<long>(int a,long b);. Но, я думаю, я должен видеть только s<long>(int a,long b);.

Что не так? У меня visual studio 2008 sp1 .

Спасибо

Обновление: Я протестировал его в Visual Studio 2010. Результат тот же. Обновление: Кажется, речь идет о c #, а не о Visual Studio.

1 Ответ

2 голосов
/ 23 мая 2011

Вы пытаетесь указать нужные параметры типа в общем определении, что не сработает.Если вы хотите иметь версии метода, которые поддерживают (для второго параметра) объекты типа int, long, and T, объявите 2 неуниверсальные перегрузки метода и одну универсальную.

void S(int a, int b)
void S(int a, long b)
void S<T>(int a, T b)

Разрешение перегрузки затем вызовет соответствующий метод на основе аргументов, сопоставляя неуниверсальные версии для точных совпадений на int или long (вы можете получитьуниверсальная версия даже с параметром int или long, если вы явно вызываете его с помощью параметра типа), в противном случае получается универсальная версия.

Примеры:

void S<T>(int a, T b)
{
    Console.WriteLine("generic method");
}

void S(int a, int b)
{
    Console.WriteLine("int overload");
}

void S(int a, long b)
{
    Console.WriteLine("long overload");
}

...

S(10, 10);
S(10, (long)10);
S(10, 10L);
S(10, 10M);
S<int>(10, 10); // uses generic
S<long>(10, 10); // uses generic & implicit conversion

Редактировать: Чтобы подробнее остановиться на пункте, упомянутом кратко выше и далее в комментариях, соответствие для перегрузок int и long должно составлять точный. Все остальные аргументы приведут к выбору универсальной версии.Если у вас нет int , но требуется перегрузка int , вам необходимо явно преобразовать аргумент до или во время вызова метода.например: S(10, (int)myShort);.

Аналогично, если у вас есть две версии метода C

void C(Mammal m) { }
void C<T>(T t) { }

с

class Tiger : Mammal { }

Вызов C(new Tiger()) приведет к использованию универсального метода,Если вы хотите перегрузку Mammal для экземпляра Tiger, вам нужна ссылка через базовый класс.Такие как

Mammal m = new Tiger();
C(m); // uses mammal overload
// or 
Tiger t = new Tiger();
C((Mammal)t); // uses mammal overload
...