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メンバーに割り当てると、「...useIConvertible...」エラーが発生します...

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()の例外を使用)。これにより、ボックス化されると、構造体ではなくInt32値がボックス化されます。

これは可能ですか?

4

1 に答える 1

0

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.

これが私が暗黙の変換を嫌う理由について、ミニ暴言を入力するのに忙しすぎました。

于 2013-01-04T23:27:25.697 に答える