Generic return type and non-nullable objects
-
11-06-2021 - |
题
I have a Sql Utility class which contains a lot of handy methods around Sql queries. This class contains the following method:
public static T ExecuteScalar<T>(
string query,
SqlConnection connection,
params SqlParameter[] parameters)
where T : class, new()
{
SqlCommand command =
CreateCommand(query, connection, parameters);
return command.ExecuteScalar() as T;
}
Is it possible to return for example Guid
objects or other non-nullable classes.
Something like this:
Guid result =
SqlUtils.ExecuteScalar<Guid>(
@"SELECT [Id] FROM [dbo].[MyTable]
WHERE [Column1] = @Param1",
connection,
new SqlParameter("@Param1", "someValue"));
解决方案
You can use default(T)
(and you should remove the generic type constraints):
SqlCommand command =
CreateCommand(query, connection, parameters);
object value = command.ExecuteScalar();
if (value == null || value is DbNull)
{
return default(T)'
}
return (T)value;
其他提示
Not the way you've written it. The as
operator may return null
if the cast fails, therefore T
has to be of a reference type.
For value types, you'll need to use a conventional cast operator (T)
. You'll also need to remove the constraint that T
is a reference type on the method definition.
public static T ExecuteScalar<T>(string query,
SqlConnection connection,
params SqlParameter[] parameters)
{
SqlCommand command = CreateCommand(query, connection, parameters);
var result = command.ExecuteScalar();
if (result is T) return (T)result;
return default(T);
}
Because the constraints of this method return a class type, you'd be able to return any object that match a class type (non-primitive). Given the nature of your method though, I don't see any need for the constraint. You should be able to remove this constraint and return any type that you can generate.