我的应用程序有一个缓存值的方法。我需要第二个方法来检查类型T的泛型参数是否实现了IEnumerable而没有实现IList。如果答案是肯定的,该方法应该执行. tolist并将其强制转换回T(参见代码示例中的注释)。
你能告诉我如何使用。tolist()来返回一个转换为T的List吗?(实际上可能吗?)
像这样:
public T ToListIfIEnumerable<T>(T value)
{
var needToCovert = TypeImplementsGenericIEnumerableButNotGenericIList(value);
if (!needToCovert)
{
return value;
}
// return value.ToList() <-- How to do that???
}
private bool TypeImplementsGenericIEnumerableButNotGenericIList<T>(T value)
{
var type = value.GetType();
var interfaces = type.GetInterfaces();
var gi = typeof(IEnumerable<>);
var gl = typeof(IList<>);
// It would be better if the next lines did't compare strings!
// Suggestions welcome...
var implementsIEnumerable = interfaces.Any(
i => i.IsGenericType && i.Name == gi.Name && i.Namespace == gi.Namespace);
var implementsIList = interfaces.Any(
i => i.IsGenericType && i.Name == gl.Name && i.Namespace == gl.Namespace);
return implementsIEnumerable && !implementsIList;
}
的背景信息:使用该方法的对象做一些类似于Lazy的事情。缓存IEnumerable在以下示例中没有多大意义:Enumerable.Range(1, 3).Select(i => Guid.NewGuid())
每次调用它都会给出新的Guid。这就是为什么我想做一个ToList()
如果您不介意使用dynamic
:
object ConvertToListIfNecessary(dynamic input)
{
return MaybeToList(input);
}
private IList<T> MaybeToList<T>(IEnumerable<T> input)
{
return input.ToList();
}
private IList<T> MaybeToList<T>(IList<T> input)
{
return input;
}
private object MaybeToList(object input)
{
// Take whatever action you want if the input *doesn't* implement
// IEnumerable<T>
}
基本上,这让dynamic
背后的智能为你做肮脏的反射工作。它可能没有手工制作的那么快,但它可能更容易正确。