我正在尝试构建 NpgsqlSimpleTypeHandler<ulong>
处理转换 ulong
值为 long
值,以便它们可以存储在我的 PostgreSQL 数据库中,反之亦然。
当我尝试调用 Npgsql 的 Int64handler.ValidtaeAndGetLength
转换后 ulong
到 long
与 Convert.ToInt64(value)
,试图通过新转换的 long
给我一个模棱两可的方法调用错误。
private readonly Int64Handler handler;
...
public override int ValidateAndGetLength(ulong value, NpgsqlParameter? parameter)
{
long val = Convert.ToInt64(value);
return handler.ValidateAndGetLength(val, parameter);
}
错误信息:Error CS0121
The call is ambiguous between the following methods or properties:
'Int64Handler.ValidateAndGetLength(float, NpgsqlParameter?)' and
'Int64Handler.ValidateAndGetLength(decimal, NpgsqlParameter?)'
为什么,即使使用 Int64Handler.ValidateAndGetLength(long, NpgsqlParameter?)
现有的,我是否会遇到模棱两可的方法调用错误?Npgsql Int64Handler documentation
[7/21/2020 14:23 EST] 更新标签以包含 C#-8.0
最佳答案
ValidateAndGetLength(long, NpgsqlParameter?)
之间的区别和 Int64Handler
中的其他重载class 是第一个方法实际上是覆盖类中的方法 NpgsqlSimpleTypeHandler<long>
实现 INpgsqlSimpleTypeHandler<long>
,而其他方法正在实现 INpgsqlSimpleTypeHandler<T>
中的方法直接接口(interface)。
来自 C# 6 draft language specification :
For example, the set of candidates for a method invocation does not include methods marked override (Member lookup), and methods in a base class are not candidates if any method in a derived class is applicable (Method invocations).
“成员查找”部分对此进行了进一步扩展:
First, a set of accessible members named N is determined:
If T is a type parameter, then the set is the union of the sets of accessible members named N in each of the types specified as a primary constraint or secondary constraint (Type parameter constraints) for T, along with the set of accessible members named N in object.
Otherwise, the set consists of all accessible (Member access) members named N in T, including inherited members and the accessible members named N in object. If T is a constructed type, the set of members is obtained by substituting type arguments as described in Members of constructed types. Members that include an override modifier are excluded from the set.
我设法用示例代码重现了这个问题:
using System;
interface IA<T>
{
int X(T x);
}
abstract class A<T> : IA<T>
{
public abstract int X(T x);
}
class B : A<long>, IA<float>, IA<decimal>
{
public override int X(long x)
{
return 8;
}
public int X(float x)
{
return 8;
}
public int X(decimal x)
{
return 8;
}
}
public class Program
{
public static void Main()
{
var b = new B();
var a = (A<long>)b;
Console.WriteLine(a.X(42L));
// Console.WriteLine(b.X(42L)); // broken
}
}
您可以使用将处理程序转换为 NpgsqlSimpleTypeHandler<long>
的解决方法。并改为调用该方法。
关于c# - 当使用 long 作为参数时,为什么在 long、float 和 decimal 方法之间存在模棱两可的方法调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63020024/