Reputation: 33
I have this code that works ok with a database with no NULL values
public T GetField<T>(SqlDataReader dr, string fieldName)
{
return (T)dr.GetValue(dr.GetOrdinal(fieldName));
}
Then I want to control the DBNull values, because they already exist in some tables and I upgraded the function like this:
public T GetField<T>(SqlDataReader dr, string fieldName) where T : new()
{
var value = dr.GetValue(dr.GetOrdinal(fieldName));
return value is DBNull ? new T() : (T)value;
}
But now, I cannot ask for GetField<string>
because string has no constructor with 0 parameters.
I have tried to create another function like the Abstract one, with no restrictions and only with string type like this
public string GetField<string>(SqlDataReader dr, string fieldName)
{
var value = dr.GetValue(dr.GetOrdinal(fieldName));
return value is DBNull ? "" : value.ToString();
}
but the answer is that they are ambiguous definitions, because T also includes string, even with the restriction applied.
I could create independent functions for each datatype, but I rather prefer the abstract solution because it is way much cleaner.
Did I miss something?
Thanks!
Upvotes: 1
Views: 1550
Reputation: 1502016
Your final method would fail because it's trying to declare a type parameter called string
.
I suggest you add another overload without the constraint on T
, but with a default value:
public T GetField<T>(SqlDataReader dr, string fieldName, T defaultValue)
{
var value = dr.GetValue(dr.GetOrdinal(fieldName));
return value is DBNull ? defaultValue : (T) value;
}
Then you'd call it as:
string x = foo.GetField(reader, "field", "");
... with the added benefit that the method isn't string-specific.
Upvotes: 5
Reputation: 28789
Here's one approach:
public T GetField<T>(SqlDataReader dr, string fieldName)
{
var value = dr.GetValue(dr.GetOrdinal(fieldName));
return value is DBNull ? default(T) : (T) value;
}
This has the added benefit of working with nullable types. Then you'd call that as:
string x = foo.GetField<string>(reader, "field") ?? "";
Which is deliberately contrived in this case -- Jon's version with a default suits you better if usually you want something other than null
returned.
Upvotes: 2