我有一个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.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
)。
我正忙着写一篇关于为什么我讨厌隐式转换的简短的咆哮。