简体   繁体   中英

how to create a generic method with optional generic parameter in c#

I have created a generic method with out parameter in c#. it will return two out parameter value which I pass list object .

public void ExecuteList<T, T1>(out List<T> obj, out List<T1> obj1, string sql, params object[] parameters) where T : class
{
    using (var db = _context)
    {
        var cmd = db.Database.Connection.CreateCommand();
        cmd.CommandText = sql;
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.AddRange(parameters);
        try
        {
            db.Database.Connection.Open();
            using (var reder = cmd.ExecuteReader())
            {
                obj = ((IObjectContextAdapter)db).ObjectContext.Translate<T>(reder).ToList();
                reder.NextResult();
                obj1 = ((IObjectContextAdapter)db).ObjectContext.Translate<T1>(reder).ToList();
            }
        }
        finally
        {
            db.Database.Connection.Close();
            cmd.Dispose();
        }
    }
} 

Call this method

List<SqlParameter> parameterList = new List<SqlParameter>(); 
parameterList.Add(new SqlParameter("@pageNo", 1));
parameterList.Add(new SqlParameter("@pageSize", 5)); 
SqlParameter[] parameters = parameterList.ToArray();
List<PostModel> PostList = new List<PostModel>();
List<Tag> TagList = new List<Tag>();
Uow.ExecuteList<PostModel,Tag>(out PostList, out TagList, "[dbo].[sp_getdata]", parameters); 

Here I pass postmodel and tag class for casting and also pass two out parameter PostList and TagList for result. It will return perfect result. But my requirement is these casting classes and out parameters should be optional. Like this: When I want one Result then pass one casting class and one Out parameter.

List<SqlParameter> parameterList = new List<SqlParameter>();
parameterList.Add(new SqlParameter("@pageNo", 1));
parameterList.Add(new SqlParameter("@pageSize", 5)); 
SqlParameter[] parameters = parameterList.ToArray();
List<PostModel> PostList = new List<PostModel>(); 
Uow.ExecuteList<PostModel>(out PostList, "[dbo].[sp_getdata]", parameters);  

And when I want two Result then pass two casting class and two out parameter.

List<SqlParameter> parameterList = new List<SqlParameter>();
parameterList.Add(new SqlParameter("@pageNo", 1));
parameterList.Add(new SqlParameter("@pageSize", 5)); 
SqlParameter[] parameters = parameterList.ToArray();
List<PostModel> PostList = new List<PostModel>();
List<Tag> TagList = new List<Tag>();
Uow.ExecuteList<PostModel,Tag>(out PostList, out TagList, "[dbo].[sp_getdata]", parameters);  

Please help me to solve my issue

You can create several overloads which will call the same private method:

private void Execute<T, T1>(ref List<T> obj, ref List<T1> obj1, string sql, params object[] parameters) where T : class
{
    using (var db = _context)
    {    
        var cmd = db.Database.Connection.CreateCommand();
        cmd.CommandText = sql;
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.AddRange(parameters);
        try
        {
            db.Database.Connection.Open();
            using (var reader = cmd.ExecuteReader())
            {
                obj = ((IObjectContextAdapter)db).ObjectContext.Translate<T>(reader).ToList();
                if(obj1 != null) {
                    reader.NextResult();
                    obj1 = ((IObjectContextAdapter)db).ObjectContext.Translate<T1>(reader).ToList();
                }                
            }
        }
        finally
        {
            db.Database.Connection.Close();
            cmd.Dispose();
        }
    }
}

public void ExecuteList<T, T1>(out List<T> obj, out List<T1> obj1, string sql, params object[] parameters) where T : class
{
    obj = new List<T>();
    obj1 = new List<T1>();
    Execute(ref obj, ref obj1, sql, parameters);
}

public void ExecuteList<T>(out List<T> obj, string sql, params object[] parameters) where T : class
{
    obj = new List<T>();
    List<object> stub = null;//generic argument doesn't matter because it will not be used
    Execute<T, object>(ref obj, ref stub, sql, parameters);
} 

Note that my first method is private and should be called only from public overloads(it's possible to add as many output parameters/overloads as you wish).

Also probably it makes sense to restrict T1 to class as well and use List<SqlParameter> instead of params object[] parameters as a last parameter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM