c# – 为什么’int’可以被视为’ushort’而不是作为扩展方法中的参数传递时,它是什么?它是一个优雅的解决方案?

我有这个扩展方法:

public static bool In<T>(this T source, params T[] list)
{
    return list.Contains(source);
}

现在我需要将上述方法用于ushort.当我尝试

ushort p = 3;
if (p.In(1, 2, 3, 4, 5))
   return;

第一行将3投射到井上.但是当3作为参数传递时,我得到了错误

‘ushort’ does not contain a definition for ‘In’ and the best extension method overload ‘Extensions.In(T, params T[])’ has some invalid arguments.

但这有效:

ushort p = 3;
if (Extensions.In(p, 1, 2, 3, 4, 5))
   return;

这很奇怪.

>为什么它适用于第二个例子,但不是第一个例子?
>什么是一个很好的选择,可以帮助我在这里?由于没有简短或ushort的文字,我没有找到比手动转换每个整数更简单的替代方法:

ushort p = 3;
if (p.In((ushort)1, (ushort)2, (ushort)3, (ushort)4, (ushort)5))
   return;

解决方法:

Why does it work with second example, but not first?

首先,让我们弄清楚编译器推断T是什么.一些参数是ushort,一些是int. ushort有一个隐式转换为int和int没有隐式转换为ushort,所以T是int.

这里的关键是C#4规范的第7.6.5.2节(强调我的):

An extension method Ci.Mj is eligible if:

  • Ci is a non-generic, non-nested class
  • The name of Mj is identifier
  • Mj is accessible and applicable when applied to the arguments as a static method as shown above
  • An implicit identity, reference or boxing conversion exists from expr to the type of the first parameter of Mj.

从ushort到int的隐式转换,但不是身份,引用或拳击转换!

所以,以下是合法的:

Extensions.In<ushort>(p, 1, 2, 3, 4, 5);
Extensions.In<int>(p, 1, 2, 3, 4, 5); // implicit conversion allowed
Extensions.In(p, 1, 2, 3, 4, 5); // T is int
p.In<ushort>(1, 2, 3, 4, 5);

但以下不是:

p.In<int>(1, 2, 3, 4, 5); // implicit conversion not allowed
p.In(1, 2, 3, 4, 5); // T is int

请注意,如果您定义In as,则可以在没有泛型的情况下获得相同的错误

public static bool In(this int source, params int[] list)
{
    return list.Contains(source);
}
上一篇:网站劫持是怎样实现的?


下一篇:将C#代码迁移到Java,无符号短和字节数组转换