由于约束错误,无法在C#中实现VB接口

时间:2015-12-15 15:15:51

标签: c# vb.net visual-studio visual-studio-2013

我无法弄清楚这一点,我不知道为什么。抱歉,这是一个糟糕的问题,我在VB中有以下界面

Public Interface IFoo  

    Sub ExecuteSQL(sql As String, ParamArray parameters() As SqlParameter)
    Sub ExecuteSQL(sql As String, useTransaction As Boolean, ParamArray parameters() As SqlParameter)
    Function ExecuteSQLAsync(sql As String, ParamArray parameters() As SqlParameter) As Task
    Function ExecuteSQLAsync(sql As String, useTransaction As Boolean, ParamArray parameters() As SqlParameter) As Task
    Function ExecuteSQL(Of T As Structure)(sql As String, ParamArray parameters() As SqlParameter) As T
    Function ExecuteSQL(Of T As Structure)(sql As String, useTransaction As Boolean, ParamArray parameters() As SqlParameter) As T
    Function ExecuteSQLAsync(Of T As Structure)(sql As String, ParamArray parameters() As SqlParameter) As Task(Of T)
    Function ExecuteSQLAsync(Of T As Structure)(sql As String, useTransaction As Boolean, ParamArray parameters() As SqlParameter) As Task(Of T)

End Interface

当我在C#中实现接口时,我收到以下错误。

  

方法ExecuteSQL(string,bool,params System.Data.SqlClient.SqlParameter [])的类型参数'T'的约束必须与接口方法IFoo.ExecuteSQL(string,bool)的类型参数'T'的约束相匹配,params System.Data.SqlClient.SqlParameter [])'。考虑使用显式接口实现

这是接口的C#实现。我不确定为什么在使用时会出现错误:

  

其中T:struct

public class Foo : IFoo
{
    public T ExecuteSQL<T>(string sql, bool useTransaction, params System.Data.SqlClient.SqlParameter[] parameters) where T : struct
    {
        throw new NotImplementedException();
    }

    public T ExecuteSQL<T>(string sql, params System.Data.SqlClient.SqlParameter[] parameters) where T : struct
    {
        throw new NotImplementedException();
    }

    public void ExecuteSQL(string sql, bool useTransaction, params System.Data.SqlClient.SqlParameter[] parameters)
    {
        throw new NotImplementedException();
    }

    public void ExecuteSQL(string sql, params System.Data.SqlClient.SqlParameter[] parameters)
    {
        throw new NotImplementedException();
    }

    public Task<T> ExecuteSQLAsync<T>(string sql, bool useTransaction, params System.Data.SqlClient.SqlParameter[] parameters) where T : struct
    {
        throw new NotImplementedException();
    }

    public Task<T> ExecuteSQLAsync<T>(string sql, params System.Data.SqlClient.SqlParameter[] parameters) where T : struct
    {
        throw new NotImplementedException();
    }

    public Task ExecuteSQLAsync(string sql, bool useTransaction, params System.Data.SqlClient.SqlParameter[] parameters)
    {
        throw new NotImplementedException();
    }

    public Task ExecuteSQLAsync(string sql, params System.Data.SqlClient.SqlParameter[] parameters)
    {
        throw new NotImplementedException();
    }
}

enter image description here

1 个答案:

答案 0 :(得分:7)

VB和C#编译器在将泛型类型参数约束为值类型时会生成不同的IL(请注意C#编译器生成的附加.ctor ([mscorlib]System.ValueType约束)。

VB:

instance !!T ExecuteSQL<valuetype T>(string sql,
              bool useTransaction,
              class [System.Data]System.Data.SqlClient.SqlParameter[] parameters) cil managed

C#:

instance !!T ExecuteSQL<valuetype .ctor ([mscorlib]System.ValueType) T>(string sql,
              bool useTransaction,
              class [System.Data]System.Data.SqlClient.SqlParameter[] parameters) cil managed

不同的方法签名会导致错误消息指示的不匹配。

我认为要让VB编译器生成类似的东西,你也必须添加New约束 - 这是编译器不允许的。因此,据我所知,没有办法明确实现该接口。

(我使用C#5编译器进行了检查,没有使用VS 2015的新Roslyn编译器,它可能表现不同)

更新

正如@Luisgrs所指出的,VS 2015中包含的新Roslyn VB编译器现在以与C#编译器相同的方式生成泛型约束。因此,一种解决方案是更新编译器/ Visual Studio版本。