Cannot convert type via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion

前端 未结 3 701
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-07 23:14

In C#, if I have a parameter for a function where the parameter type is of an interface, how do a pass in an object that implements the interface.

Here is an example

相关标签:
3条回答
  • 2021-01-07 23:46

    You can't do that, you have to convert list

    exampleList.Cast<ICustomRequired>().ToList();
    
    0 讨论(0)
  • 2021-01-08 00:00

    You cannot cast a List of one type to a List of a different type.

    And if you think about it, you would be glad that you can't. Imagine the havoc you could cause if it was possible:

     interface ICustomRequired
     {
     }
    
     class ImplementationOne : ICustomRequired
     {
     }
    
     class ImplementationTwo: ICustomRequired
     {
     }
    
     var listOne = new List<ImplementationOne>();
     var castReference = listOne as List<ICustomRequired>();
     // Because you did a cast, the two instances would point
     // to the same in-memory object
    
     // Now I can do this....
     castReference.Add(new ImplementationTwo());
    
     // listOne was constructed as a list of ImplementationOne objects,
     // but I just managed to insert an object of a different type
    

    Note, however, that this line of code is legal:

     exampleList as IEnumerable<ICustomRequired>;
    

    This would be safe, because IEnumerable does not provide you with any means to add new objects.

    IEnumerable<T> is actually defined as IEnumerable<out t>, which means the type parameter is Covariant.

    Are you able to change the parameter of the function to IEnumerable<ICustomRequired>?

    Otherwise your only option will be to create a new List.

    var newList = (exampleList as IEnumerable<ICustomRequired>).ToList();
    

    or

    var newList = exampleList.Cast<ICustomRequired>().ToList();
    
    0 讨论(0)
  • 2021-01-08 00:00

    In additional to List.Cast, C#'s generics provide a good support for Covariance and contravariance. This example causes it to work in the way I think you originally intended.

    public class Program
    {
        public static void Main()
        {
             Foo(new List<Fim>());
        }
    
        public static void Foo<T>(List<T> bar) where T : IFim
        {
            throw new NotImplementedException();
        }
    
        public class IFim{}
        public class Fim : IFim{}
    }
    
    0 讨论(0)
提交回复
热议问题