2

我有一个类成员类型为 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.Value 成员时,我最终得到一个“...使用 IConvertible ...”错误...

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.Value 分配上被调用。所以问题 #1 是为什么这样做而不是分配基础 Int32 值?

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

随意批评我编写的代码的任何方面,但我真的希望能得到很好的答案。

(编辑添加)我将重新表述我的问题......

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

这可能吗?

4

1 回答 1

0

SqlParameter.Value是类型化object的,因​​此编译器不知道调用隐式运算符将MyValue实例转换valint.

然而,类似以下的东西应该可以工作:

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.

我正忙着写一个关于这就是我讨厌隐式转换的原因的迷你咆哮。

于 2013-01-04T23:27:25.697 回答