给定一个通用方法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
调用非通用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>>
转换为Expression<Func<Stuff,bool>>
,我看起来似乎只能获得我想要的内容。这也假设我有一个测试,例如is
或as
,以确认它是可投射的。
如何完成类型测试,以及如何完成演员表?
是否有其他方法来强制调用更具体和非通用的Get
方法?请假设呼叫者必须仅通过ISomething
接口工作。
当然,如果立即调用非通用Get
而不通过Get<T>
,那将更加理想。但如果我被迫通过ISomething
界面工作,我认为这是不可能的。
仅供参考,如果可以找到一种方法使其工作 - 那么它将提供与C ++中的“traits - the else-then-if”类似的功能。
答案 0 :(得分:3)
这样的事情怎么样:
public List<T> Get<T>(Expression<Func<T,bool>> expr){
var expr2 = expr as Expression<Func<Stuff, bool>>;
if (expr2 != null){
return Get(expr2) as List<T>;
}
//...
}
此代码使ReSharper变得怪异,但似乎有效:)
如果可能,更好的选择是向ISomething添加非泛型重载。