2015-06-17 11 views
5

W języku C#, jeśli mam parametr dla funkcji, w której typem parametru jest interfejs, w jaki sposób przekazać w obiekt implementujący interfejs.Nie można przekonwertować typu poprzez konwersję referencyjną, konwersję boksu, konwersję rozpakowywania, konwersję owijającą lub konwersję typu null

Oto przykład:

Parametr dla funkcji jest następująca:

List<ICustomRequired> 

listy, która mam już to w następujący sposób:

List<CustomObject> exampleList 

CustomObject dziedziczy z ICustomRequired interfejs

Co to jest c orrect składnia przekazać exampleList jako parametr?

Tak myślałem zrobić powyższy zadanie:

exampleList as List<ICustomRequired> 

Jednak ja otrzymuję następujący błąd:

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

Thanks

Odpowiedz

9

Nie można rzucić List jednego rodzaju do List innego typu.

A jeśli o tym pomyślisz, byłbyś zadowolony, że nie możesz. Wyobraźmy sobie spustoszenie mógł spowodować gdyby to było możliwe:

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 

Należy jednak pamiętać, że ta linia kodu jest legalne:

exampleList as IEnumerable<ICustomRequired>; 

Byłoby to bezpieczne, ponieważ IEnumerable nie dostarczy Ci dowolny oznacza dodawanie nowych obiektów.

jest faktycznie zdefiniowany jako IEnumerable<out t>, co oznacza, że ​​parametr typu to Covariant.

Czy jesteś w stanie zmienić parametr funkcji na IEnumerable<ICustomRequired>?

W przeciwnym razie jedyną opcją będzie utworzenie nowej listy.

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

lub

var newList = exampleList.Cast<ICustomRequired>().ToList(); 
+0

Dziękuję za odpowiedź. – user3736648

0

Nie można tego zrobić, trzeba do listy konwersji

exampleList.Cast<ICustomRequired>().ToList(); 
0

W dodatkowy do List.Cast, C# 's generyczne zapewniają dobre wsparcie dla Covariance and contravariance. Ten przykład powoduje, że działa on zgodnie z pierwotnym zamiarem użytkownika.

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{} 
} 
Powiązane problemy