SqlParameter的隐式操作符和赋值.带有不可逆转错误的值

本文关键字:不可逆转 错误 操作符 SqlParameter 赋值 | 更新日期: 2023-09-27 17:50:48

我有一个Int32的类成员类型,但是要求这个成员的. tostring()方法需要返回一个特殊格式化的Int32版本。因此,我创建了一个带有隐式操作符的结构体,它保留了简单的值赋值语义,并且我可以重写。tostring()…

public struct MyValue
{
    private int _val;
    public MyValue(int val) { _val = val; }
    public static implicit operator int(MyValue value)
    {
        return value._val;
    }
    public static implicit operator MyValue(int value)
    {
        return new MyValue(value);
    }
    public override string ToString()
    {
        return _val.ToString("0000000000");
    }
}

在典型用法中,它的功能与预期一致。然而,当我分配给SqlParameter。值成员,我最终得到一个"…

string connString = "Server=svr;Database=db;Trusted Connection=Yes";
string sql = "SELECT * FROM [tbl] WHERE [val] = @val";
MyValue val = 256;
SqlParameter parm = new SqlParameter("@val", SqlDbType.Int);
parm.Value = val;
using ( SqlConnection conn = new SqlConnection(connString) )
{
    conn.Open();
    using ( SqlCommand cmd = new SqlCommand(sql, conn) )
    {
        cmd.Parameters.Add(parm);
        using ( SqlDataReader rdr = cmd.ExecuteReader() )
        {
            while ( !rdr.Read() ) { }
            rdr.Close();
        }
    }
    conn.Close();
}

在调试时,看起来我的结构上的. tostring()方法在SqlParameter上被调用。赋值。问题1是为什么它这样做,而不是分配底层Int32值?

相关问题#2是为什么初始赋值不生成错误,因为错误是在SqlCommand.ExecuteReader()方法中生成的?

请随意批评我所写代码的任何方面,但我真的希望我的问题得到好的答案。

(编辑添加)我将重新措辞我的问题…

我需要创建一个完全模仿Int32的值数据类型(使用. tostring()异常),这样当它被装箱时,Int32值被装箱而不是结构体。

这可能吗?

SqlParameter的隐式操作符和赋值.带有不可逆转错误的值

SqlParameter.Value类型为object,因此编译器不知道调用隐式运算符将MyValue实例val转换为int

但是,像下面这样的东西应该可以工作:

static SqlParameter GetIntSqlParameter(string name, int value)
{
    SqlParameter parm = new SqlParameter(name, SqlDbType.Int);
    parm.Value = value;
    return parm;
}

可以被称为:

SqlParameter parm = GetIntSqlParameter("@val", val);

或者正如Jeppe在注释中指出的那样,强制转换为int也可以工作(但是操作符也可以定义为explicit)。

我正忙着写一篇关于为什么我讨厌隐式转换的简短的咆哮。