【问题标题】:Return different Lists at one method C#在一种方法 C# 中返回不同的列表
【发布时间】:2018-01-02 21:54:18
【问题描述】:

如何以一种方法返回不同的对象列表?我有一些方法,返回一些类型的列表,我不知道 Parse 方法应该返回什么

public static [Something here (IList???)] Parse(string filePath)
{
    string[] lines = File.ReadAllLines(filePath);

    for (int i = 0; i < lines.Length; i++)
    {
        string recordId = lines[i].Substring(0, 2);
        switch (recordId)
        {
            case "00":

                return Parse00(lines[i]); //public static List<mainInfo> Parse00(string line);

            case "11":

                return Parse11(lines[i]); //public static List<param> Parse11(string line);

          …  
          …

        }
    }
}

【问题讨论】:

  • mainInfo 是从 param 继承还是从某个常见类型继承?
  • @LasseV.Karlsen,DB 没有不同的表
  • 你想做什么?在您的示例中,您只返回第一行。我假设您想解析所有行,对吗?
  • 您可以返回 List&lt;object&gt;List&lt;dynamic&gt; 然后(或任何其他集合类型),仅此而已。但是,您的代码并不完全清楚。在你的 switch 语句中匹配 case 的第一行将返回一些东西并中止循环,这段代码真的代表你想要完成的事情吗?
  • @LasseV.Karlsen:您关于继承的问题在这里有些无关紧要。即使它们继承,List&lt;MyDerivedType&gt; 也不能隐式转换为 List&lt;MyBaseType&gt;See this SO answer for clarification。我知道这不是您在评论中明确说明的内容,但我推断这就是您提出这一思路的地方(我认为其他读者也是如此)

标签: c# .net visual-studio list return


【解决方案1】:

为了使其工作,您需要一个所有“记录”都继承自的基本类型。所以叫它Record

public class Record
{
    // some shared properties
}

public class ParamRecord : Record
{
    // param-specific properties
}   

public class MainInfoRecord : Record
{
    // main-specific properties
}   

现在您可以返回List&lt;Record&gt;

【讨论】:

    【解决方案2】:

    我只想向您指出,如果您阅读这样的行,您会节省一些内存。

    var lines = File.ReadLines(fileName); foreach (var line in lines) // Process line

    您可以在What's the fastest way to read a text file line-by-line? 上了解更多信息。

    此外,我会将您的方法重命名为 ParseFile 以避免混淆,并使用 @CodeCaster 方法创建类层次结构。一旦你有了类层次结构,你就可以编写一个工厂来为你做解析。

    【讨论】:

      【解决方案3】:

      使用List&lt;dynamic&gt; 作为返回类型。 例如:

          public static List<dynamic> Parse(string filePath)
      {
          string[] lines = File.ReadAllLines(filePath);
      
          for (int i = 0; i < lines.Length; i++)
          {
              string recordId = lines[i].Substring(0, 2);
              switch (recordId)
              {
                  case "00":
      
                      return Parse00(lines[i]).ToList<dynamic>; //public static List<mainInfo> Parse00(string line);
      
                  case "11":
      
                      return Parse11(lines[i]).ToList<dynamic>; //public static List<param> Parse11(string line);
      
                …  
                …
      
              }
          }
      }
      

      【讨论】:

      • 无法将类型“System.Collections.Generic.List”隐式转换为“System.Collections.Generic.List
      • 如果这是要走的路,您将不得不构建一个新列表并将更具体列表中的所有项目添加到这个更开放的列表中。你不能投。比如:return xyz.ToList&lt;dynamic&gt;();
      • return Parse00(lines[i]).ToList();
      • 你也可以让你的方法返回类型为对象,这样它就可以接受任何东西
      【解决方案4】:

      您需要 mainInfoparam-classes 继承相同的基类或接口:

      interface MyInterface { ... }
      class Param : MyInterface { ... }
      class MainInfo : MyInterface { ... }
      

      现在您可以返回所需类型的列表:

      string recordId = lines[i].Substring(0, 2);
      switch (recordId)
      {
          case "00":
              return Parse00(lines[i]); //public static List<mainInfo> Parse00(string line);
          case "11":
              return Parse11(lines[i]); //public static List<param> Parse11(string line);
      

      但是,您的方法需要返回 Enumerable&lt;MainInfo&gt;IEnumerable&lt;Param&gt;,因为 List 不是协变的,这意味着您不能将 List&lt;MainInfo&gt; 分配给 List&lt;MyInterface&gt;,但是您可以将前者分配给 IEnumerable&lt;MyInterface&gt;因为IEnumerable 是协变的。

      最后,由于两个可能的返回值都可以分配给IEnumerable&lt;MyInterface&gt;,您可以将其用作Parse 方法的返回类型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多