David DB
asked on
Use string as T with New
I have a method that should get data from SQL Server.
This method should put the data into the specified variable or class. It can be a single column, or multiple columns.
This is a example code (that has nothing to do with SQL server):
It works perfectly with int, long and other value types, and classes. But NOT with string.
This works:
This gives a compiler error:
How can I get it to accept strings also, so it can return string ?
This method should put the data into the specified variable or class. It can be a single column, or multiple columns.
This is a example code (that has nothing to do with SQL server):
internal static T GetValue<T>(T value) where T : new()
{
if (typeof(T).GetType().IsValueType)
{
return value;
}
else
{
T dummyClass = new T();
return dummyClass;
}
}
It works perfectly with int, long and other value types, and classes. But NOT with string.
This works:
var test = Globals.GetValue<int>(1);
This gives a compiler error:
var test1 = Globals.GetValue<string>("2");
How can I get it to accept strings also, so it can return string ?
ASKER
If I remove new, how can I create a class T in the method ?
Hi,
What are you trying to achieve here?
What are you trying to achieve here?
ASKER
To fill a variable or class with values from SQL server. I have one single record version, and one list version:
But it will not accept string as T
internal static async Task<List<T>> ExecuteSQLSPReaderAsync<T>(SqlConnection conn, string storedProcedure, params SqlParameter[] parametersAndvalues) where T : new()
{
try
{
List<T> retList = new List<T>();
#pragma warning disable CA2100 // Review SQL queries for security vulnerabilities
using (SqlCommand cmd = new SqlCommand(storedProcedure, conn))
#pragma warning restore CA2100 // Review SQL queries for security vulnerabilities
{
cmd.CommandType = CommandType.StoredProcedure;
for (int counter = 0; counter < parametersAndvalues.Length; counter++)
{
cmd.Parameters.Add(parametersAndvalues[counter]);
if (cmd.Parameters[counter].Value == null)
{
cmd.Parameters[counter].Value = DBNull.Value;
}
}
cmd.Connection = conn;
if (!conn.State.HasFlag(ConnectionState.Open)) { conn.Open(); }
SqlDataReader reader = await cmd.ExecuteReaderAsync().ConfigureAwait(false);
SqlDataReader retData = reader;
if ((typeof(T).IsValueType) | (typeof(T)==typeof(object)))
{
while (reader.Read())
{
T newRec=new T();
if (!(reader.GetValue(0) is DBNull))
{
newRec = (T)reader.GetValue(0);
}
retList.Add(newRec);
}
}
else
{
T newRec = new T();
var thisType = newRec.GetType();
var theseProperties = thisType.GetProperties();
while (reader.Read())
{
newRec = new T();
foreach (var field in theseProperties)
{
if (!reader.IsDBNull(reader.GetOrdinal(field.Name)))
{
var obj = reader.GetValue(reader.GetOrdinal(field.Name));
thisType.GetProperty(field.Name).SetValue(newRec, obj);
}
}
retList.Add(newRec);
}
}
return retList;
}
}
catch (Exception)
{ return null; }
}
But it will not accept string as T
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Perfect solution!
where T : new()
requires type T to have public default constructor:
The new constraint specifies that any type argument in a generic class declaration must have a public parameterless constructor. To use the new constraint, the type cannot be abstract.
string does not have one. Try to remove where T : new() from the definition for string.