我有这个扩展方法:
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);
}