Sony
Sony

Reputation: 7196

method that accepts a generic class as argument in c#

In my project I have a generic class, which is used to store data and pass to another function:

public class SqlCommandParameter<T>
{
    public string ParameterName { get;private set; }
    public SqlDbType SqlDbType { get; private set; }
    public T SqlDbValue { get; private set; }

    public SqlCommandParameter(string parameterName, SqlDbType sqlDbType, T sqlDbValue)
    {
        ParameterName = parameterName;
        SqlDbType = sqlDbType;
        SqlDbValue = sqlDbValue;
    }
}

but when I tried to pass instances of this to another function, it gives the error: Cannot resolve T. Here is my method declaration:

 public Task<DataTable> GetDataAsync(int? id, string commandTextQuery, CommandType commandType,params SqlCommandParameter<T>[] parameters )
    { ... } 

Since the number or values to the stored procedure is different, I'm passing it as params. How can I pass the generic class to the function in the proper way? Can anyone suggest a way to do this without error?

Upvotes: 2

Views: 167

Answers (1)

Kit
Kit

Reputation: 21709

You can make GetDataAsync() a generic method, GetDataAsync<T>() but all parameters will be limited to whatever T happens to be when you call the method:

GetDataAsync(..., new SqlCommandParameter<int>(), new SqlCommandParameter<int>());

will work, but

GetDataAsync(..., new SqlCommandParameter<int>(), new SqlCommandParameter<string>());

will not. One option would be to derive your generic SqlCommandParameter<T> from a non-generic SqlCommandParameter and pass in the non-generic to a non-generic GetDataAsync():

public abstract class SqlCommandParameter
{
    public string ParameterName { get; private set; }
    public SqlDbType SqlDbType { get; private set; }

    protected SqlCommandParameters(string parameterName, SqlDbType sqlDbType)
    {
        ParameterName = parameterName;
        SqlDbType = sqlDbType;
    }
}

public class SqlCommandParameter<T>: SqlCommandParameter
{
    public T SqlDbValue { get; private set; }

    public SqlCommandParameter(string parameterName, SqlDbType sqlDbType, T sqlDbValue): base(parameterName, sqlDbType)
    {
        SqlDbValue = sqlDbValue;
    }
}

With the above, this call below will work:

GetDataAsync(..., new SqlCommandParameter<int>(), new SqlCommandParameter<string>());

if the signature of the method is

public Task<DataTable> GetDataAsync(
    int? id,
    string commandTextQuery,
    CommandType commandType,
    params SqlCommandParameter[] parameters )  { ... }

Another solution is to create a container for your generic parameters and pass in that container to the method without params because you will be passing in just that one collection.

Upvotes: 4

Related Questions