C# 将泛型方法参数转换为特定类型
给定一个通用方法C# 将泛型方法参数转换为特定类型,c#,linq,generics,lambda,expression,C#,Linq,Generics,Lambda,Expression,给定一个通用方法Get,该方法采用以下参数 Expression<Func<T,bool>> foo 我的意图是让泛型方法Get调用非泛型Get,如果exprLambdaExpression特别采用Stuff类型的参数。但在上面的代码中并不是这样 如果我运行这个代码 ISomething foo = new Something(); var result = foo.Get((Stuff x) => x.Alpha < 20); ISomething
Get
,该方法采用以下参数
Expression<Func<T,bool>> foo
我的意图是让泛型方法Get
调用非泛型Get
,如果expr
LambdaExpression
特别采用Stuff
类型的参数。但在上面的代码中并不是这样
如果我运行这个代码
ISomething foo = new Something();
var result = foo.Get((Stuff x) => x.Alpha < 20);
ISomething foo=new Something();
var结果=foo.Get((Stuff x)=>x.Alpha<20);
…调用的函数是Get
。这并不奇怪,即使非泛型的Get
是更好的匹配,因为Get
是ISomething接口中唯一可用的匹配。所以这是可以的
但是一旦执行了Get
方法,我希望使用名为expr
的相同参数调用非泛型Get
。考虑到我观察到的行为,似乎只有将表达式
转换为表达式
,我才能得到我想要的。这还假设我有一个测试,如is
或as
,以确认它是可浇铸的
型式试验是如何进行的,铸件是如何进行的
是否有其他方法强制调用更具体和非泛型的Get
方法?请假定调用者只能通过ISomething
接口工作
诚然,如果立即调用非泛型的Get
,而根本不经过Get
,这将更加理想。但是如果我被迫通过ISomething
接口工作,我认为这是不可能的
FYI,如果可以找到一种方法来实现这一工作,那么它将提供一些类似于“C++中的”功能。
< P>这样的事情: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){
//...
}
}
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>;
}
//...
}
公共列表获取(表达式expr){
var expr2=expr作为表达式;
if(expr2!=null){
返回Get(expr2)作为列表;
}
//...
}
这段代码让ReSharper抓狂,但它似乎可以工作:)
如果可能的话,一个更好的选择是向ISomething添加一个非泛型重载。您是否尝试过使用GetType()?能否请您更好地解释一下您的用例?对我来说,这个设计似乎过于复杂,我确信有一种优雅的面向对象的方法可以简化它。@rmayer06:在底部添加了一个额外的注释和链接,以阐明为什么这很有用。所以你无法控制接口定义?@mayer06:正确。接口是固定的。实际上,接口是我的,所以技术上我可以修改它……但关键是要有一个设计,允许我添加实现的专门化,而不影响接口。再次,模糊地喜欢C++的“特征”。这正是我尝试的第一件事,结果发现它不起作用。我看到了你的答案,然后再试一次——它很有效。无论什么至少它起作用了。:)我喜欢这个解决方案:-)但我真的为那个不得不弄明白你的代码在做什么的家伙感到抱歉…;-)
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>;
}
//...
}