2016-07-07 1 views
1

Не могли бы вы объяснить, почему следующий состав не работает и решение проблемы.InvalidCastException: Невозможно сделать общий родословный Список объектов

У меня есть GroupedResult:

public class GroupedResult<TKey, TElement> 
{ 
    public TKey Key { get; set; } 

    private readonly IEnumerable<TElement> source; 

    public GroupedResult(TKey key, IEnumerable<TElement> source) 
    { 
     this.source = source; 
     this.Key = key; 
    } 
} 

public class Bacon 
{ 
} 

Я хотел бы забрасывать List<string, Bacon> к List<string, object>. Я пробовал следующие и другие способы.

var list = new List<GroupedResult<string, Bacon>> 
    { 
     new GroupedResult<string, Bacon>("1", new List<Bacon>()), 
     new GroupedResult<string, Bacon>("2", new List<Bacon>()) 
    }; 

var result = list.Cast<GroupedResult<string, object>>().ToList(); 

Но я всегда получаю следующее сообщение об ошибке:

InvalidCastException: Unable to cast object of type 'GroupedResult 2[System.String,UserQuery+Bacon]' to type 'GroupedResult 2[System.String,System.Object]'.

+4

Классы являются инвариантными, поэтому 'GropuedResult ' не является 'GroupedResult '. – Lee

ответ

1

Для этого вам нужно будет использовать интерфейс вместо типа класса.

public interface IGroupResult<TKey, out TElement> 
{ 
    TKey Key { get; set; } 
} 

public class GroupedResult<TKey, TElement> : IGroupResult<TKey, TElement> 
{ 
    public TKey Key { get; set; } 

    private readonly IEnumerable<TElement> source; 

    public GroupedResult(TKey key, IEnumerable<TElement> source) 
    { 
     this.source = source; 
     this.Key = key; 
    } 
} 

public class Bacon 
{ 

} 

Тогда вы могли бы сделать что-то вроде

IGroupResult<string, Bacon> g = new GroupedResult<string, Bacon>("1", new List<Bacon>()); 

var result = (IGroupResult<string, object>)g; 

Это потому, что ковариации разрешено только на интерфейсах и делегатов, но не классы. Обратите внимание, что вы должны только отмечать тип как со-вариант, если он выходит только из интерфейса (метод возврата метода и свойства только для чтения).

Хотя вы должны спросить себя, почему вы хотите что-то придать object, когда вы работаете с дженериками. Основная особенность дженериков заключается в том, чтобы избежать использования типа object в качестве улова, и это может указывать на недостаток вашего дизайна, который вы, возможно, захотите переосмыслить.

0

Было бы лучше начать со строкой GroupedResult <, объект>, то вы можете сделать это

new GroupedResult<string, object>("2", new List<Bacon>()) 
0

почему Арен 'y вы используете GroupedResult<string, object> вместо GroupedResult<string, Bacon>? например:

var list = new List<GroupedResult<string, object>> 
    { 
     new GroupedResult<string, object>("1", new List<Bacon>()), 
     new GroupedResult<string, object>("2", new List<Bacon>()) 
    }; 
0

Вы можете использовать метод Cast в своем классе GroupedResult и использовать его для кастинга!

public class GroupedResult<TKey, TElement> 
{ 
    public TKey Key { get; set; } 

    private readonly IEnumerable<TElement> source; 

    public GroupedResult(TKey key, IEnumerable<TElement> source) 
    { 
     this.source = source; 
     this.Key = key; 
    } 

    public GroupedResult<TKey, object> Cast() 
    { 
     return new GroupedResult<TKey, object>(Key, source.Cast<object>()); 
    } 
} 

public class Bacon 
{ 
} 

static void Main(string[] args) 
{ 

    var list = new List<GroupedResult<string, Bacon>> 
    { 
     new GroupedResult<string, Bacon>("1", new List<Bacon>()), 
     new GroupedResult<string, Bacon>("2", new List<Bacon>()) 
    }; 

    // var result = list.Cast<GroupedResult<string, object>>().ToList(); 
    List<GroupedResult<string,object>> result = list.Select(B => B.Cast()).ToList(); 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^