-1

I'm actually trying to solve a problem with List in C#.

Here are my classes:

public class  A {
    public int ID { get; set; }
    public string tag { get; set; }
}

public class B1 : A {
    public int info { get; set; }
}
public class B2 : A {
    public C info { get; set; }
}
public class C {
   ...
}

I would like to have a function like that:

public List<A> function(typeEnum t)

To be able to return an object instance of type List<B1> or List<B2> and so on, depending on the requested typeEnum, as a List<A>.

My problem is the different type of info in B1 and B2 classes.

  • 2
    What is `typeEnum`? Would something like `List function()` work? Then you could call `var listOfB1 = function()` – canton7 May 26 '21 at 08:43
  • Do you want a list of instances, or do you want types? Your `function` returns instances. – ProgrammingLlama May 26 '21 at 08:45
  • typeEnum is an enum, it help me to chose if I return B1 or B2 List. – hcurtillet May 26 '21 at 08:48
  • I want a list of instances, I've tryied to use but it does not work. – hcurtillet May 26 '21 at 08:49
  • Are those new instances, or already-existing instances that you want? – ProgrammingLlama May 26 '21 at 08:50
  • They are B1 and B2 instances – hcurtillet May 26 '21 at 08:52
  • Note that you cannot assign a List type to a variable with a type of List. For the reason, consider: Given base `List` and derived `List` and `List`. If you could do `List mlist = myListOfDogs;` then you could do `mlist.Add(new Cat());` and chaos would ensue as you've added a Cat to a list of Dog! – Matthew Watson May 26 '21 at 08:53
  • They are different because the type of "info" is different in B1 and B2. – hcurtillet May 26 '21 at 08:53
  • Does this answer your question? [How to create a new object instance from a Type](https://stackoverflow.com/questions/752/how-to-create-a-new-object-instance-from-a-type) and [How to dynamically create a class?](https://stackoverflow.com/questions/3862226/how-to-dynamically-create-a-class) –  May 26 '21 at 08:54
  • 1
    That doesn't help me sorry – hcurtillet May 26 '21 at 08:59
  • @hcurtillet [True generic polymorphism](https://stackoverflow.com/questions/58247604/how-to-do-generic-polymorphism-on-open-types-in-c/58247676#58247676) is not yet available in C# since we don't have the [diamond operator](https://stackoverflow.com/questions/58570948/how-to-create-list-of-open-generic-type-of-classt/58571001#58571001) working for that, thus you can't return either a `List` or `List` as `List`, sorry. You only can return `List` where you can put any child. Else *you need as many method as many expected returned types*. –  May 26 '21 at 09:16
  • 1
    @hcurtillet See also [C# generic inheritance and covariance part 2](https://stackoverflow.com/questions/14263964/c-sharp-generic-inheritance-and-covariance-part-2/14264436#14264436) and [C# variance problem: Assigning List as List](https://stackoverflow.com/questions/2033912/c-sharp-variance-problem-assigning-listderived-as-listbase/58783084) –  May 26 '21 at 09:20
  • @hcurtillet Concerning the problem about `info`, can you add more details on how it will be used. Perhaps you can use `dynamic`, or not... I think rather of a generic `B : A` to have `T info`. –  May 26 '21 at 09:36
  • Your issue is that List<> is not covarient (see https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/covariance-contravariance/) using IEnumerable is more plausibly if you do not want to subsequently alter what is in the List – bwakabats May 26 '21 at 11:31

2 Answers2

0

Although your question is unclear (hence the comments), what you might be searching for is a LINQ extension.

var list_of_a = new List<A>{ new A(), new B1(), new B1(), new B2(), new C() };
var list_of_b = list_of_a.OfType<B1>();

where list_of_b only contains the elements that are of B1.

Corniel Nobel
  • 421
  • 4
  • 12
-1

You could have a switch-case to do the OfType for you based on the typeEnum:

public List<A> function(typeEnum t, List<A> listToFilter)
{
    switch (t)
    {
        case typeEnum.B1:
            return listToFilter.OfType<B1>().ToList();

        case typeEnum.B2:
            return listToFilter.OfType<B2>().ToList();

        default:
            throw new NotImplementedException("Please implement " + t);
    }

}

Or you can use a Linq Where function to filter. If your typeEnum values match the name of the type you are filtering by, you could do something like:

public List<A> function(typeEnum t, List<A> listToFilter)
{
    return listToFilter.Where(item => item.GetType().Name == t.ToString()).ToList();
}

In both cases, you'll need to cast the items in the returned list to have access to the 'info' property as they'll be returned as 'A' objects, but they are still instances of the type you filtered on.

Slate
  • 3,189
  • 1
  • 31
  • 32