C# 返回函数指针
我正在尝试创建一个类似于asp mvc中的url生成器,只是我们的方法经常更改参数和断开页面 有人知道有没有可能强迫c#允许从如下委托返回类似事件的语法:C# 返回函数指针,c#,C#,我正在尝试创建一个类似于asp mvc中的url生成器,只是我们的方法经常更改参数和断开页面 有人知道有没有可能强迫c#允许从如下委托返回类似事件的语法: new UrlBuilder2<FakeController>(x => { return x.ActionWithInt; }); public class MyForm { public void MyMethod() { // Something here } public void Method
new UrlBuilder2<FakeController>(x => { return x.ActionWithInt; });
public class MyForm {
public void MyMethod() {
// Something here
}
public void MethodWithParams(int i, string str) {
// Something here
}
}
class MyClass {
public void MyMethod() {}
}
class UrlBuilder3<T> {
Expression<Func<T, Action>> info;
public UrlBuilder3(Expression<Func<T, Action>> info) {
this.info = info;
}
public override string ToString() {
UnaryExpression exp = (UnaryExpression)info.Body;
MethodCallExpression createDelegate = (MethodCallExpression)exp.Operand;
// 0-Action,1-x,2-Delegate as Constant
ConstantExpression methodArgument = (ConstantExpression)createDelegate.Arguments[2];
MethodInfo method = (MethodInfo)methodArgument.Value;
return string.Format("{0}/{1}.aspx", typeof(T).Name, method.Name);
}
}
[Test]
public void UrlByDelegate() {
new UrlBuilder3<MyClass>(x => x.MyMethod).ToString()
.Should().Be.EqualTo("MyClass/MyMethod.aspx");
}
newurlbuilder2(x=>{return x.ActionWithInt;});
该类与此类似:
public class UrlBuilder<TController>
{
public UrlBuilder2(Func<TController, TType> action)
{
}
}
MyForm/MyMethod.aspx
公共类UrlBuilder
{
公共UrlBuilder2(函数操作)
{
}
}
基本上我想知道TType使用什么类型。或者如果可能的话
编辑-
我(如果可能的话)只想使用该方法,类似于分配事件的方式(
clickEvent=+myMethod;
)不完全确定您想要实现什么,但假设您想要生成指向以下内容的链接:
public class UrlBuilder<TController>
{
public UrlBuilder2(Func<TController, TType> action)
{
}
}
MyForm/MyMethod.aspx
基于以下Web表单(或任何其他类):
new UrlBuilder2<FakeController>(x => { return x.ActionWithInt; });
public class MyForm {
public void MyMethod() {
// Something here
}
public void MethodWithParams(int i, string str) {
// Something here
}
}
class MyClass {
public void MyMethod() {}
}
class UrlBuilder3<T> {
Expression<Func<T, Action>> info;
public UrlBuilder3(Expression<Func<T, Action>> info) {
this.info = info;
}
public override string ToString() {
UnaryExpression exp = (UnaryExpression)info.Body;
MethodCallExpression createDelegate = (MethodCallExpression)exp.Operand;
// 0-Action,1-x,2-Delegate as Constant
ConstantExpression methodArgument = (ConstantExpression)createDelegate.Arguments[2];
MethodInfo method = (MethodInfo)methodArgument.Value;
return string.Format("{0}/{1}.aspx", typeof(T).Name, method.Name);
}
}
[Test]
public void UrlByDelegate() {
new UrlBuilder3<MyClass>(x => x.MyMethod).ToString()
.Should().Be.EqualTo("MyClass/MyMethod.aspx");
}
您可以使用此生成器(包括测试):
类UrlBuilder2{
私有只读表达式callExpression;
公共UrlBuilder2(表达式调用Expression){
this.callExpression=callExpression;
}
公共重写字符串ToString(){
MethodCallExpression调用=(MethodCallExpression)callExpression.Body;
StringBuilder sb=新的StringBuilder();
sb.AppendFormat(“{0}/{1}.aspx”,call.Object.Type.Name,call.Method.Name);
var分隔符=“?”;
var formalParams=call.Method.GetParameters();
for(int i=0;i您可能需要增强UrlBuilder2,但这应该可以让您开始
如果您只想使用方法的名称来生成链接,可以执行以下操作:
new UrlBuilder2<FakeController>(x => { return x.ActionWithInt; });
public class MyForm {
public void MyMethod() {
// Something here
}
public void MethodWithParams(int i, string str) {
// Something here
}
}
class MyClass {
public void MyMethod() {}
}
class UrlBuilder3<T> {
Expression<Func<T, Action>> info;
public UrlBuilder3(Expression<Func<T, Action>> info) {
this.info = info;
}
public override string ToString() {
UnaryExpression exp = (UnaryExpression)info.Body;
MethodCallExpression createDelegate = (MethodCallExpression)exp.Operand;
// 0-Action,1-x,2-Delegate as Constant
ConstantExpression methodArgument = (ConstantExpression)createDelegate.Arguments[2];
MethodInfo method = (MethodInfo)methodArgument.Value;
return string.Format("{0}/{1}.aspx", typeof(T).Name, method.Name);
}
}
[Test]
public void UrlByDelegate() {
new UrlBuilder3<MyClass>(x => x.MyMethod).ToString()
.Should().Be.EqualTo("MyClass/MyMethod.aspx");
}
class-MyClass{
public void MyMethod(){}
}
类UrlBuilder3{
表达信息;
公共UrlBuilder3(表达式信息){
this.info=info;
}
公共重写字符串ToString(){
UnaryExpression=(UnaryExpression)info.Body;
MethodCallExpression createDelegate=(MethodCallExpression)exp.Operand;
//0-动作、1-x、2-委托作为常量
ConstantPression方法参数=(ConstantPression)createDelegate.Arguments[2];
MethodInfo方法=(MethodInfo)methodArgument.Value;
返回string.Format(“{0}/{1}.aspx”,typeof(T.Name,method.Name);
}
}
[测试]
public void UrlByDelegate(){
新的UrlBuilder3(x=>x.MyMethod).ToString()
.Should().Be.EqualTo(“MyClass/MyMethod.aspx”);
}
棘手的事情是正确解析表达式树。上面的代码适用于此特定示例,但您需要检查它是否适用于所有情况。您可以返回一个函数指针,即c#中的委托,如下所示
public delegate int mydelegate(string s);
public class Test
{
mydelegate MyFunc(string s)
{
return (astring => astring.Length + s.Length);
}
}
这将允许您将函数的输出附加到事件
var test = new Test();
someevent += test.MyFunc("this is a test");
假设someevent接受了与委托具有相同签名的函数 这样,如果我向MyMethod添加一个参数,那么它仍然会在使用表达式链接到它的任何地方中断。这就是我想要避免的,不。它甚至不会编译。我添加了如何从方法向查询字符串传递参数。这基本上就是现有URl生成器所做的。我(如果可能的话)只想使用这个方法,类似于分配事件的方式(clickEvent=+myMethod;),我为此添加了另一个示例。希望这就是你需要的。这正是您在示例中提出的问题和显示的内容。如果您想传递参数,我已经在前面提供了解决方案。这将要求每个可能的控制器操作都有一个委托,因此不是很优雅。您可以通过泛型创建各种委托签名,即公共委托T myreturningdelegate();