【问题标题】:A problem with generic method overloading泛型方法重载的问题
【发布时间】:2011-05-23 05:18:40
【问题描述】:

我有以下方法:

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

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

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

当我想将它用作s&lt;long&gt;(10,10) 时,我会在工具提示中看到这些覆盖。 s&lt;long&gt;(int a,int b); s&lt;long&gt;(int a,long b);。但是,我想我必须只看到s&lt;long&gt;(int a,long b);

怎么了?我有 visual studio 2008 sp1

谢谢

更新:我在 Visual Studio 2010 中测试过,结果是一样的。 更新:似乎是关于 c# 而不是 Visual Studio。

【问题讨论】:

  • ints 可以自动提升为longs,所以这是正确的行为。
  • 这些不是覆盖 - 它们是重载。而且你没有声明这样的泛型方法......

标签: c# generics methods overloading


【解决方案1】:

您试图在泛型定义中直接提供所需的类型参数,但这是行不通的。如果您希望拥有支持 int, long, and T 类型对象(对于第二个参数)的方法版本,请声明 2 个非泛型方法重载和一个泛型方法。

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

然后,重载解析将根据参数调用适当的方法,匹配非泛型版本以精确匹配 intlong(您可以获得泛型版本,即使使用intlong 参数(如果您使用类型参数显式调用它),否则获取泛型版本。

例子:

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

编辑:为了扩展上面简要提到的一点并进一步在 cmets 中,intlong 重载的匹配需要精确。 所有其他参数将导致选择通用版本。如果您没有 int想要 int 重载,则需要在方法调用之前或期间显式转换参数。例如:S(10, (int)myShort);

同样,如果你有两个版本的方法C

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

class Tiger : Mammal { }

调用C(new Tiger()) 将导致使用泛型方法。如果您想要 Mammal 实例的 Mammal 重载,则需要通过基类进行引用。比如

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

【讨论】:

  • 这是正确的方法,但你还是要小心一点。例如,假设您调用 S(10, myShort)。通用版、int 版还是长版哪个更好?很多人期望“short 去 int,所以 int 版本更好”,但实际上正确的答案是 S 匹配 exactly 而 int 和 long 版本是不精确匹配的,所以通用版本获胜。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-16
  • 1970-01-01
相关资源
最近更新 更多