Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/461.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 返回函数指针_C# - Fatal编程技术网

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

我正在尝试创建一个类似于asp mvc中的url生成器,只是我们的方法经常更改参数和断开页面

有人知道有没有可能强迫c#允许从如下委托返回类似事件的语法:

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;ic.MyMethod()).ToString(); str.Should().Be.EqualTo(“MyForm/MyMethod.aspx”); } [测试] public void可以使用params()构建UrlByMethod{ var str=newurlbuilder2(c=>c.MethodWithParams(2,“hello”)).ToString(); str.Should().Be.EqualTo(“MyForm/MyMethod.aspx?i=2&str=hello”); } 所有这些都将允许您保持链接类型的安全性,并将利用重构优势。
您可能需要增强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();