我有一个通用的QueryProvider,可以根据请求提供某种类型的数据(序列)。
在提供数据之前,我会检查所请求的类型IsAssignable是否属于我可以提供的类型。
编译器对从int thirdPos = str.IndexesOf(']').Take(3).Last();
到IEnumerable<TData>
的演员表示满意,但却抱怨将IEnumerable<TResult>
投射到TData
TResult
编译器错误CS0030无法转换类型&#39; TData&#39;到&#39; TResult&#39;
class MyClass<TData>
{
private IEnumerable<TData> GetSequence() {return Enumerable.Empty<TData>(); }
private TData GetSingleValue() { return default(TData); }
public TResult GetResult<TResult>()
{
TResult result;
if (typeof(TResult).IsAssignableFrom(typeof(IEnumerable<TData>)))
{ // we can Assign IEnumerable<TData> to TResult
IEnumerable<TData> data = GetSequence();
result = (TResult)data;
}
else if (typeof(TResult).IsAssignableFrom(typeof(TData)))
{ // we can assing TData to TResult:
TData data = GetSingleValue();
result = (TResult)data;
为什么将 }
else
throw new InvalidOperationException("Can't provide data");
return result;
}
}
投射到IEnumerable<TData>
没有问题,但是不可能将TData投射到TResult?
添加一些评论之后
实际上,IEnumerable<TResult>
与问题无关。困扰我的是IsAssignable
转换没有问题,而直接转换是。
当然,where子句解决了这个问题,但这只会改变一个问题:为什么IEnumerable
没有where子句,为什么直接转换需要where子句:
IEnumerable
如果编译器无法证明我的显式演员是不正确的,那么它是否会让我受益?
答案 0 :(得分:0)
你的问题和你的代码没有排成一行。您的代码未尝试将TData
投射到TResult
。它试图将IEnumerable<TData>
转换为`TResult。
如果IEnumerable<TData>
到IEnumerable<TResult>
有效。 IEnumerable<TData>
到TResult
不会。
答案 1 :(得分:0)
IsAssignableFrom并不真正链接到任何一个,它是运行时检查,而检查编译器的类型是编译时间检查。
它不允许你将TData转换为TResult,因为它无法验证转换,因为这两种类型之间没有定义任何关系。 IEnumerable在此期间是一个接口,因此强制转换可能有效 - 转换接口与转换具体类型参数不同。