给定一个采用以下参数的通用方法Get<T>
...
Expression<Func<T,bool>> foo
在该方法主体中,我想测试“T”是否为 typeof(Stuff),如果是,则进行转换:
Expression<Func<Stuff,bool>> boo = (???) foo;
我期望的第一反应是“不需要投射它,Stuff
如果传入它就已经是类型了。” 但是我发现在方法调度方面不是这样!!
所以是的,我需要测试和投射,但不知道如何。
以下是为什么以及在何处需要这样做的背景。
我有这样的代码:
public class Stuff {
public int Alpha;
}
interface ISomething {
List<T> Get<T>(Expression<Func<T,bool>> lambda);
}
public class Something : ISomething {
List<T> Get<T>(Expression<Func<T,bool>> expr){
//...
//Makes non-recursive call to non-generic 'Get' method.
//Works as expected.
Get((Stuff x) => x.Alpha > 10);
//UH-OH! makes recursive call to Get<T> even when T is typeof(Stuff)!
//This is where casting is needed!
Get(expr);
//...
}
List<Stuff> Get(Expression<Func<Stuff,bool>> expr){
//...
}
}
我的意图是让泛型方法Get<T>
调用非泛型Get
,如果expr
LambdaExpression
具体采用 type 参数Stuff
。但这不是上面代码中发生的情况。
如果我运行此代码...
ISomething foo = new Something();
var result = foo.Get((Stuff x) => x.Alpha < 20);
...调用的函数是Get<T>
. 这并不奇怪,即使非泛型Get
是更好的匹配,因为Get<T>
它是 ISomething 接口中唯一可用的匹配。所以这没关系。
但是一旦Get<T>
方法执行,我希望Get
使用名为expr
. Expression<Func<T,bool>>
鉴于我观察到的行为,看起来只有将to 转换为我才能得到我想要的东西Expression<Func<Stuff,bool>>
。这也假设我有一个测试,比如is
or as
,以确认它是可铸造的。
类型测试是如何完成的,演员是如何完成的?
Get
是否有另一种方法来强制调用更具体和非通用的方法?请假设调用者必须ISomething
只通过接口工作。
Get
当然,如果不经过任何处理就立即调用非泛型会更加理想Get<T>
。但如果我被迫通过ISomething
界面工作,我认为这是不可能的。
仅供参考,如果可以找到一种方法来完成这项工作 - 然后它将提供类似于C++ 中的“特征 - else-then-if ”的功能。