У меня есть тип члена класса 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, я получаю ошибку "... use 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()), чтобы, когда он помещается в коробку, значение Int32 помещалось в коробку вместо структуры.
Это возможно?
"0000000000"
вы также можете использовать"D10"
. - person Jeppe Stig Nielsen   schedule 05.01.2013System.Data.SqlClient
? Согласно сообщению об ошибке, это может работать, если ваша структура реализует интерфейсIConverible
.Int32
реализует это, поэтому вы можете перенаправить каждый вызов на явную реализацию интерфейсаInt32
. Но это очень уродливый код. Как я уже говорил в другом месте, почему бы просто не сказатьparm.Value = (int)val;
в таких случаях? - person Jeppe Stig Nielsen   schedule 05.01.2013