C# 我能让这个方法返回泛型返回类型吗?

C# 我能让这个方法返回泛型返回类型吗?,c#,generics,C#,Generics,我能使这个方法通用吗 public static List<int> GetUnshippedOrders(string server,string port,string database,string username,string password, string orderStatus) { var orderNumbers = new List<int>(); using (var conn = ConnectToMySq

我能使这个方法通用吗

  public static List<int> GetUnshippedOrders(string server,string port,string database,string username,string password, string orderStatus)
  {
        var orderNumbers = new List<int>();
        using (var conn = ConnectToMySql(server, port, database, username, password))
        {            
           var command = new MySqlCommand("SELECT OrderNumber FROM orders WHERE OrderStatus = @orderStatus;", conn);
            command.Parameters.AddWithValue("@orderStatus", orderStatus);
            var reader = command.ExecuteReader();
            while (reader.Read())
            {
                orderNumbers.Add(Convert.ToInt32(reader[0])); 
            }
        } 
        return orderNumbers;
   }
我希望能够处理各种返回类型,因为引用的订单号将根据连接到的数据库的模式而变化,我希望不必为每个可能的返回类型重载此方法,并且我希望学习泛型

数据库模式由各种web服务决定,这些服务都不在我的控制之下。
还需要特别注意的是,orderStatus可以是多种类型,主要是string和int,可能是这样的:

public static List<T> GetUnshippedOrders<T>(string server,string port,string database,string username,string password, string orderStatus) where T : class
{
    var orderNumbers = new List<T>();
    using (var conn = ConnectToMySql(server, port, database, username, password))
    {            
       var command = new MySqlCommand("SELECT OrderNumber FROM orders WHERE OrderStatus = @orderStatus;", conn);
        command.Parameters.AddWithValue("@orderStatus", orderStatus);
        var reader = command.ExecuteReader();
        while (reader.Read())
        {
            orderNumbers.Add((T)(reader[0])); 
        }
    } 
    return orderNumbers;
}

也许是这样的:

public static List<T> GetUnshippedOrders<T>(string server,string port,string database,string username,string password, string orderStatus) where T : class
{
    var orderNumbers = new List<T>();
    using (var conn = ConnectToMySql(server, port, database, username, password))
    {            
       var command = new MySqlCommand("SELECT OrderNumber FROM orders WHERE OrderStatus = @orderStatus;", conn);
        command.Parameters.AddWithValue("@orderStatus", orderStatus);
        var reader = command.ExecuteReader();
        while (reader.Read())
        {
            orderNumbers.Add((T)(reader[0])); 
        }
    } 
    return orderNumbers;
}
如果调用方知道返回类型

如果调用方知道订单号的预期类型,则可以将定义更改为

public static List<T> GetUnshippedOrders<T>(string server,string port,string database,string username,string password, string orderStatus)
用法:

List<int> orderNumbers = GetUnshippedOrders<int>(...);
如果方法知道返回类型

如果GetUnshippedOrders方法必须确定订单号的类型,则不能使用泛型。

如果调用方知道返回类型

如果调用方知道订单号的预期类型,则可以将定义更改为

public static List<T> GetUnshippedOrders<T>(string server,string port,string database,string username,string password, string orderStatus)
用法:

List<int> orderNumbers = GetUnshippedOrders<int>(...);
如果方法知道返回类型


如果方法GetUnshippedOrders必须确定订单号的类型,则不能使用泛型。

如果确定返回类型的逻辑是该方法的内部逻辑,则泛型返回类型不会有帮助,因为调用泛型方法时需要能够指定返回类型。您可以将返回类型更改为List,然后在方法返回后将转换回具体类型。虽然很难看,但它很管用


如果调用方知道调用该方法时需要什么类型,您可以简单地将List改为List,并以这种方式支持泛型。

如果确定返回类型的逻辑是该方法内部的,那么泛型返回类型将不会有帮助,因为您需要能够在调用泛型方法时指定返回类型。您可以将返回类型更改为List,然后在方法返回后将转换回具体类型。虽然很难看,但它很管用


如果调用方知道调用该方法时所需的类型,您可以简单地将List更改为List,并以这种方式支持泛型。

类似这样的用法不要忘记使用:

public static List<T> GetUnshippedOrders<T>(string server,string port,string database,string username,string password, string orderStatus, Func<IDataReader, T> factoryMethod)
  {
        var results = new List<T>();
        using (var conn = ConnectToMySql(server, port, database, username, password))
        {            
           using (var command = new MySqlCommand("SELECT OrderNumber FROM orders WHERE OrderStatus = @orderStatus;", conn))
            {
               command.Parameters.AddWithValue("@orderStatus", orderStatus);
               using (var reader = command.ExecuteReader())
               {
                 while (reader.Read())
                 {
                   results.Add(factoryMethod(reader)); 
                 }
               }
             }
        } 
        return results;
   }

像这样的东西不要忘记使用:

public static List<T> GetUnshippedOrders<T>(string server,string port,string database,string username,string password, string orderStatus, Func<IDataReader, T> factoryMethod)
  {
        var results = new List<T>();
        using (var conn = ConnectToMySql(server, port, database, username, password))
        {            
           using (var command = new MySqlCommand("SELECT OrderNumber FROM orders WHERE OrderStatus = @orderStatus;", conn))
            {
               command.Parameters.AddWithValue("@orderStatus", orderStatus);
               using (var reader = command.ExecuteReader())
               {
                 while (reader.Read())
                 {
                   results.Add(factoryMethod(reader)); 
                 }
               }
             }
        } 
        return results;
   }

如果不能始终使用强制转换将结果转换为t,则可能需要添加一个额外的Func参数,以允许使用自定义转换方法将对象转换为所需的结果。@vittore-我正试图与代码保持一致,并在那里强制转换。您的建议也适用:如果您不能始终使用强制转换将结果转换为t,您可能需要添加一个额外的Func参数,以允许使用自定义转换方法将对象转换为所需的结果。@vittore-我试图与代码保持一致,并在那里强制转换。你的建议也会起作用:downvoter:来自常见问题解答:最重要的是,诚实。如果你看到错误的信息,就否决它。添加注释,指出具体错误。提供你自己的更好答案。最好的-编辑和改进现有的问题和答案!投票人:从常见问题中:最重要的是,诚实。如果你看到错误的信息,就否决它。添加注释,指出具体错误。提供你自己的更好答案。最好的-编辑和改进现有的问题和答案!如果在调用之前无法确定类型,那么当方法返回时,您将如何在下一行代码中确定它?@RuneFS-理论上,您将知道要返回的类型范围。您可以根据这些类型测试返回的对象,然后进行适当的强制转换。@JustinNiessner谢谢-按照我测试所需的方式工作。是的,您可以,但这不仅是丑陋的,而且是更糟糕的。我相信它会带来的代码版本的Belzebub@RuneFS-有时这是一种必要的邪恶。如果在调用之前无法确定类型,那么在下一行代码(即当方法返回时)中如何确定类型?@RuneFS-理论上,您知道要返回的类型范围。您可以根据这些类型测试返回的对象,然后进行适当的强制转换。@JustinNiessner谢谢-按照我测试所需的方式工作。是的,您可以,但这不仅是丑陋的,而且是更糟糕的。我相信它会带来的代码版本的Belzebub@RuneFS-有时这是一种必要的邪恶。远没有被误导的GOTO那么糟糕。