2016-07-07 75 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

为什么AREN '你用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

您可以在您的GroupedResult课程中使用Cast方法并使用它进行投射!

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(); 
} 
相关问题