0

How can I return different lists of objects at one method? I have some methods, that returns some types of Lists, and I don't know what Parse method should return

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);

          …  
          …

        }
    }
}
6
  • Does mainInfo inherit from param, or vice versa, or do they inherit from some common type? Commented Jul 27, 2017 at 9:11
  • @LasseV.Karlsen, no there are different tables at DB Commented Jul 27, 2017 at 9:14
  • What do you want to do? In your example you are returning only the first line. I assume, that you want to parse all lines, right? Commented Jul 27, 2017 at 9:15
  • You can return List<object> or List<dynamic> then (or any other collection type), that's about it. Your code isn't altogether clear, however. The first line that matches a case in your switch statement will return something and abort the loop, is this code really representative for what you want to accomplish? Commented Jul 27, 2017 at 9:15
  • @LasseV.Karlsen: Your question about inheritance is somewhat irrelevant here. Even if they inherit, a List<MyDerivedType> cannot implicitly be cast to a List<MyBaseType>. See this SO answer for clarification. I know this is not something you've explicitly stated in your comment, but I infer that that's where you were taking this train of thought to (as would other readers, I assume) Commented Jul 27, 2017 at 9:38

4 Answers 4

1

In order for this to work, you need a base type that all "records" inherit from. So call it Record:

public class Record
{
    // some shared properties
}

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

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

Now you can return a List<Record>.

Sign up to request clarification or add additional context in comments.

Comments

1

I would just like to point out to you that you would save some memory if you read lines like this.

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

You can learn more about this on What's the fastest way to read a text file line-by-line?.

Furthermore, I would rename your method to ParseFile to avoid confusion and use @CodeCaster approach with creating class hierarchy. Once you have class hierarchy you can write a Factory that would do the parsing for you.

Comments

0

Use List<dynamic> as a return type. Ex:

    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);

          …  
          …

        }
    }
}

4 Comments

Cannot implicitly convert type 'System.Collections.Generic.List<DB.Model.param>' to 'System.Collections.Generic.List<dynamic>'
If this is the way to go you will have to construct a new list and add all the items from the more specific list into this more open list. You can't cast. Something like: return xyz.ToList<dynamic>();
return Parse00(lines[i]).ToList<dynamic>();
you can also make your method return type as object so that it can accept anything
0

You need your mainInfo and param-classes to inherit the same base-class or interface:

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

Now you can return lists of the desired types:

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);

However your methods need to return Enumerable<MainInfo> or IEnumerable<Param> as List isn´t covariant which means you can´t assign a List<MainInfo> to List<MyInterface>, however you can assign the former to IEnumerable<MyInterface> as IEnumerable is covariant.

Finally as both possible return-values are assignable to IEnumerable<MyInterface> you could use that as return-type for your Parse-method.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.