【发布时间】:2017-09-06 11:10:28
【问题描述】:
我正在尝试使用类型字典解析泛型类型T 到实例。
当T 是IEnumerable<> 时,我会得到一个包含该字典中所有实例的LINQ Select 查询。但是,当我尝试返回该查询时,我无法将其转换回 T。我得到以下异常:
Additional information: Unable to cast object of type 'WhereSelectListIterator`2[System.Func`2[DiContainer.IServicesContainer,System.Object],System.Object]' to type 'System.Collections.Generic.IEnumerable`1[Tester.IService]'.
代码:
public T Resolve<T>()
{
Type typeToResolve = typeof(T);
if (m_TypeToConcrete.ContainsKey(typeToResolve))
{
return (T)m_TypeToConcrete[typeToResolve].GetSingle();
}
if (DetermineIfExactlyIEnumerable(typeToResolve))
{
Type underlyingType = typeToResolve.GetGenericArguments().First();
if (m_TypeToConcrete.ContainsKey(underlyingType))
{
// Throws invalid cast exception
return (T)m_TypeToConcrete[underlyingType].GetEnumerable();
}
}
}
public class FactoryMethodsForType
{
private List<Func<IServicesContainer, object>> m_FactoryMethods;
private IServicesContainer m_Container;
public FactoryMethodsForType(IServicesContainer container)
{
m_Container = container;
m_FactoryMethods = new List<Func<IServicesContainer, object>>();
}
public void AddFactoryMethod(Func<IServicesContainer, object> method)
{
m_FactoryMethods.Add(method);
}
public object GetSingle()
{
return m_FactoryMethods.Last().Invoke(m_Container);
}
public IEnumerable<object> GetEnumerable()
{
// Lazy
return m_FactoryMethods.Select(m => m.Invoke(m_Container));
}
}
【问题讨论】:
-
GetEnumerable获取字典的枚举数。你的意思是(T)m_TypeToConcrete[underlyingType] -
m_TypeToConcrete的类型是什么?InvalidCastException的消息是什么? -
您试图在该方法中做太多事情。这里的假设是您正在创建自己的 DI 容器。第二组代码看起来像是在尝试创建 ResolveAll 方法。您可能需要检查您的设计
-
m_TypeToConcrete是Dictionary<Type, FactoryMethodsForType>类型,而GetEnumerable是我写的一个方法,在下面。我想你的意思是AsEnumerable。 -
保持简单愚蠢 (KISS) ,我想如果你期待 IEnumerable 那就选择 IEnumerable
。
标签: c# linq generics ienumerable