In C#, is it possible to cast a List to List?

前端 未结 5 1924
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-28 05:29

I want to do something like this:

List childList = new List();
...
List parentList = childList;

How

相关标签:
5条回答
  • 2020-11-28 05:55

    Using LINQ:

    List<Parent> parentList = childList.Cast<Parent>().ToList();
    

    Documentation for Cast<>()

    0 讨论(0)
  • 2020-11-28 05:59

    You can do this by using a Linq approach of the apply extension method, i.e.:

    List<Parent> parentList = childList.Cast<Parent>().ToList();
    
    0 讨论(0)
  • 2020-11-28 06:05

    yes, you can do it like

    var result = List.And(x => x.Parent.All(b => b.ParentId == value));
    
    0 讨论(0)
  • 2020-11-28 06:10

    Casting directly is not allowed because there's no way to make it typesafe. If you have a list of giraffes, and you cast it to a list of animals, you could then put a tiger into a list of giraffes! The compiler wouldn't stop you, because of course a tiger may go into a list of animals. The only place the compiler can stop you is at the unsafe conversion.

    In C# 4 we'll be supporting covariance and contravariance of SAFE interfaces and delegate types that are parameterized with reference types. See here for details:

    https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/covariance-contravariance/

    0 讨论(0)
  • 2020-11-28 06:12

    Back in 2009 Eric teased us that things would change in C# 4. So where do we stand today?

    The classes used in my answer can be found at the bottom. To make this easier to follow, we will use a Mammal class as "parent", and Cat and Dog classes as "children". Cats and dogs are both mammals, but a cat is not a dog and a dog is not a cat.

    This still isn't legal, and can't be:

    List<Cat> cats = new List<Cat>();
    
    List<Mammal> mammals = cats;
    

    Why not? Cats are mammals, so why can't we assign a list of cats to a List<Mammal>?

    Because, if we were allowed to store a reference to a List<Cat> in a List<Mammal> variable we would then be able to compile the following code to add a dog to a list of cats:

    mammals.Add(new Dog());
    

    We mustn't allow that! Remember, mammals is just a reference to cats. Dog does not descend from Cat and has no business being in a list of Cat objects.

    Starting with .NET Framework 4, several generic interfaces have covariant type parameters declared with the out Generic Modifier keyword introduced in C# 4. Amongst these interfaces is IEnumerable<T> which of course is implemented by List<T>.

    That means we can now cast a List<Cat> to an IEnumerable<Mammal>:

    IEnumerable<Mammal> mammalsEnumerable = cats;
    

    We can't add a new Dog to mammalsEnumerable because IEnumerable<out T> is a "read-only" interface i.e. it has no Add() method, but we can now use cats wherever a IEnumerable<Mammal> can be consumed. For example, we can concatenate mammalsEnumerable with a List<Dog> to return a new sequence:

    void Main()
    {
        List<Cat> cats = new List<Cat> { new Cat() };
        IEnumerable<Mammal> mammalsEnumerable =
            AddDogs(cats); // AddDogs() takes an IEnumerable<Mammal>
        Console.WriteLine(mammalsEnumerable.Count()); // Output: 3. One cat, two dogs.
    }
    
    public IEnumerable<Mammal> AddDogs(IEnumerable<Mammal> parentSequence)
    {
        List<Dog> dogs = new List<Dog> { new Dog(), new Dog() };
        return parentSequence.Concat(dogs);
    }
    

    Class definitions:

    public abstract class Mammal { }
    
    public class Cat: Mammal { }
    
    public class Dog : Mammal { }
    
    0 讨论(0)
提交回复
热议问题