C# 在c中重载具有委托的方法#

C# 在c中重载具有委托的方法#,c#,.net,delegates,overloading,C#,.net,Delegates,Overloading,是否有某种方法可以使用委托“重载”函数?我希望有一个系统,在这个系统中,我可以在构造函数中传递匿名函数,并将其保存在成员变量中。数据类型不是真正的问题,但是传递的函数可以有一个或两个参数。我曾尝试在委托定义中使用(params double[]vals),但这会使传递的匿名函数变得复杂,并且允许的参数比应该允许的多 所以我创建了两个空方法来保存这两种类型。例如: public class OpWrapper { public int operands; //the number

是否有某种方法可以使用委托“重载”函数?我希望有一个系统,在这个系统中,我可以在构造函数中传递匿名函数,并将其保存在成员变量中。数据类型不是真正的问题,但是传递的函数可以有一个或两个参数。我曾尝试在委托定义中使用(params double[]vals),但这会使传递的匿名函数变得复杂,并且允许的参数比应该允许的多

所以我创建了两个空方法来保存这两种类型。例如:

public class OpWrapper
{
    public int operands;      //the number of operands this operator needs.
    public int precedence;    //the precedence this operator gets when calculating.
    public bool rightAssoc;   //whether or not this operator is right associative (true) or left associative (false).

    public delegate double evalDelegate(double a, double b);
    public delegate double calcDelegate(double a);
    public evalDelegate eval; //method used for two value inputs. Assigned in constructor.
    public calcDelegate calc; //method used for single value input. Assigned in constructor.

    //constructor initializes all variables.
    public OpWrapper(int o, int p, evalDelegate f, bool a = false)
    {
        operands = o;
        precedence = p;
        rightAssoc = a;
        eval = new evalDelegate(f);
    }
    //overloaded constructor assigns the proper method.
    public OpWrapper(int o, int p, calcDelegate f, bool a = false)
    {
        operands = o;
        precedence = p;
        rightAssoc = a;
        calc = new calcDelegate(f);
    }

    public double evaluate(params double[] values)
    {
        //do stuff
        if (operands == 1)
        {
            return calc(values[0]);
        }
        else
        {
            return eval(values[0], values[1]);
        }
        //more stuff
    }

}
最后,我想做的是:

public class OpWrapper
{
    public int operands;      //the number of operands this operator needs.
    public int precedence;    //the precedence this operator gets when calculating.
    public bool rightAssoc;   //whether or not this operator is right associative (true) or left associative (false).

    public delegate double evalDelegate(double a, double b);
    public delegate double calcDelegate(double a);
    public ???????? calc; //method that does the passed function.

    //constructor initializes all variables.
    public OpWrapper(int o, int p, evalDelegate f, bool a = false)
    {
        operands = o;
        precedence = p;
        rightAssoc = a;
        eval = new evalDelegate(f);
    }
    //overloaded constructor assigns the proper method.
    public OpWrapper(int o, int p, calcDelegate f, bool a = false)
    {
        operands = o;
        precedence = p;
        rightAssoc = a;
        calc = new calcDelegate(f);
    }

    public double evaluate(params double[] values)
    {
        //do stuff
        if (operands == 1)
        {
            return calc(values[0]);
        }
        else
        {
            return calc(values[0], values[1]);
        }
        //more stuff
    }

}

我还不太熟悉C#,但肯定有一种方法可以做到这一点,而不必定义一个或另一个将不使用的委托实例。

.Net提供了一些现成的有用委托类型;也就是对一个void返回方法的操作和对一个保留参数的方法的Func。它们为匿名委托提供了类型安全性,并为您所需的内容提供了一种干净的方法,这种方法类似于命令或策略模式

还可以使用表达式内联声明委托,如下所示:

public void InvokeAction(Action invoke)
{
    invoke();
}

InvokeAction(() => Console.WriteLine(...));
=>本质上意味着“进入”,如果你有参数,你会在箭头之前声明它们:

(arg1, arg2) => ...
在现代.Net编码中,表达式和Action/Func几乎完全取代了匿名委托

如果类上有Action类型的属性,则直接将其作为方法调用

public Action Calc { get; set; }

Calc = () => Console.WriteLine(...);

Calc();

.Net提供了一些现成的有用委托类型;也就是对一个void返回方法的操作和对一个保留参数的方法的Func。它们为匿名委托提供了类型安全性,并为您所需的内容提供了一种干净的方法,这种方法类似于命令或策略模式

还可以使用表达式内联声明委托,如下所示:

public void InvokeAction(Action invoke)
{
    invoke();
}

InvokeAction(() => Console.WriteLine(...));
=>本质上意味着“进入”,如果你有参数,你会在箭头之前声明它们:

(arg1, arg2) => ...
在现代.Net编码中,表达式和Action/Func几乎完全取代了匿名委托

如果类上有Action类型的属性,则直接将其作为方法调用

public Action Calc { get; set; }

Calc = () => Console.WriteLine(...);

Calc();

.Net提供了一些现成的有用委托类型;也就是对一个void返回方法的操作和对一个保留参数的方法的Func。它们为匿名委托提供了类型安全性,并为您所需的内容提供了一种干净的方法,这种方法类似于命令或策略模式

还可以使用表达式内联声明委托,如下所示:

public void InvokeAction(Action invoke)
{
    invoke();
}

InvokeAction(() => Console.WriteLine(...));
=>本质上意味着“进入”,如果你有参数,你会在箭头之前声明它们:

(arg1, arg2) => ...
在现代.Net编码中,表达式和Action/Func几乎完全取代了匿名委托

如果类上有Action类型的属性,则直接将其作为方法调用

public Action Calc { get; set; }

Calc = () => Console.WriteLine(...);

Calc();

.Net提供了一些现成的有用委托类型;也就是对一个void返回方法的操作和对一个保留参数的方法的Func。它们为匿名委托提供了类型安全性,并为您所需的内容提供了一种干净的方法,这种方法类似于命令或策略模式

还可以使用表达式内联声明委托,如下所示:

public void InvokeAction(Action invoke)
{
    invoke();
}

InvokeAction(() => Console.WriteLine(...));
=>本质上意味着“进入”,如果你有参数,你会在箭头之前声明它们:

(arg1, arg2) => ...
在现代.Net编码中,表达式和Action/Func几乎完全取代了匿名委托

如果类上有Action类型的属性,则直接将其作为方法调用

public Action Calc { get; set; }

Calc = () => Console.WriteLine(...);

Calc();

这对你有帮助。在本文中,我刚刚将您的calc变量初始化为object,它是所有类型(int、class、delegate等)的基类型,在evaluate方法中,我将它从object转换为相应的类型

public class OpWrapper
{
    public int operands;      //the number of operands this operator needs.
    public int precedence;    //the precedence this operator gets when calculating.
    public bool rightAssoc;   //whether or not this operator is right associative (true) or left associative (false).

    public delegate double evalDelegate(double a, double b);
    public delegate double calcDelegate(double a);
    public object calc; //method that does the passed function.

    //constructor initializes all variables.
    public OpWrapper(int o, int p, evalDelegate f, bool a = false)
    {
        operands = o;
        precedence = p;
        rightAssoc = a;
        calc = new evalDelegate(f);
    }
    //overloaded constructor assigns the proper method.
    public OpWrapper(int o, int p, calcDelegate f, bool a = false)
    {
        operands = o;
        precedence = p;
        rightAssoc = a;
        calc = new calcDelegate(f);
    }

    public double evaluate(params double[] values)
    {
        //do stuff
        if (operands == 1)
        {
            return (calc as calcDelegate)(values[0]);
        }
        else
        {
            return (calc as evalDelegate)(values[0], values[1]);
        }
        //more stuff
    }

}

这对你有帮助。在本文中,我刚刚将您的calc变量初始化为object,它是所有类型(int、class、delegate等)的基类型,在evaluate方法中,我将它从object转换为相应的类型

public class OpWrapper
{
    public int operands;      //the number of operands this operator needs.
    public int precedence;    //the precedence this operator gets when calculating.
    public bool rightAssoc;   //whether or not this operator is right associative (true) or left associative (false).

    public delegate double evalDelegate(double a, double b);
    public delegate double calcDelegate(double a);
    public object calc; //method that does the passed function.

    //constructor initializes all variables.
    public OpWrapper(int o, int p, evalDelegate f, bool a = false)
    {
        operands = o;
        precedence = p;
        rightAssoc = a;
        calc = new evalDelegate(f);
    }
    //overloaded constructor assigns the proper method.
    public OpWrapper(int o, int p, calcDelegate f, bool a = false)
    {
        operands = o;
        precedence = p;
        rightAssoc = a;
        calc = new calcDelegate(f);
    }

    public double evaluate(params double[] values)
    {
        //do stuff
        if (operands == 1)
        {
            return (calc as calcDelegate)(values[0]);
        }
        else
        {
            return (calc as evalDelegate)(values[0], values[1]);
        }
        //more stuff
    }

}

这对你有帮助。在本文中,我刚刚将您的calc变量初始化为object,它是所有类型(int、class、delegate等)的基类型,在evaluate方法中,我将它从object转换为相应的类型

public class OpWrapper
{
    public int operands;      //the number of operands this operator needs.
    public int precedence;    //the precedence this operator gets when calculating.
    public bool rightAssoc;   //whether or not this operator is right associative (true) or left associative (false).

    public delegate double evalDelegate(double a, double b);
    public delegate double calcDelegate(double a);
    public object calc; //method that does the passed function.

    //constructor initializes all variables.
    public OpWrapper(int o, int p, evalDelegate f, bool a = false)
    {
        operands = o;
        precedence = p;
        rightAssoc = a;
        calc = new evalDelegate(f);
    }
    //overloaded constructor assigns the proper method.
    public OpWrapper(int o, int p, calcDelegate f, bool a = false)
    {
        operands = o;
        precedence = p;
        rightAssoc = a;
        calc = new calcDelegate(f);
    }

    public double evaluate(params double[] values)
    {
        //do stuff
        if (operands == 1)
        {
            return (calc as calcDelegate)(values[0]);
        }
        else
        {
            return (calc as evalDelegate)(values[0], values[1]);
        }
        //more stuff
    }

}

这对你有帮助。在本文中,我刚刚将您的calc变量初始化为object,它是所有类型(int、class、delegate等)的基类型,在evaluate方法中,我将它从object转换为相应的类型

public class OpWrapper
{
    public int operands;      //the number of operands this operator needs.
    public int precedence;    //the precedence this operator gets when calculating.
    public bool rightAssoc;   //whether or not this operator is right associative (true) or left associative (false).

    public delegate double evalDelegate(double a, double b);
    public delegate double calcDelegate(double a);
    public object calc; //method that does the passed function.

    //constructor initializes all variables.
    public OpWrapper(int o, int p, evalDelegate f, bool a = false)
    {
        operands = o;
        precedence = p;
        rightAssoc = a;
        calc = new evalDelegate(f);
    }
    //overloaded constructor assigns the proper method.
    public OpWrapper(int o, int p, calcDelegate f, bool a = false)
    {
        operands = o;
        precedence = p;
        rightAssoc = a;
        calc = new calcDelegate(f);
    }

    public double evaluate(params double[] values)
    {
        //do stuff
        if (operands == 1)
        {
            return (calc as calcDelegate)(values[0]);
        }
        else
        {
            return (calc as evalDelegate)(values[0], values[1]);
        }
        //more stuff
    }

}

我会把我的帽子扔进拳击场

下面是如何使用Func

public class OpWrapper
{
    public int operands;      //the number of operands this operator needs.
    public int precedence;    //the precedence this operator gets when calculating.
    public bool rightAssoc;   //whether or not this operator is right associative (true) or left associative (false).

    public object func;

    //constructor initializes all variables.
    public OpWrapper(int p, Func<double, double> f, bool a = false)
    {
        //No need to pass in o, we can infer from context that its a single parameter
        operands = 1;
        precedence = p;
        rightAssoc = a;
        func = f;
    }
    //overloaded constructor assigns the proper method.
    public OpWrapper(int p, Func<double, double, double> f, bool a = false)
    {
        //No need to pass in o, we can infer from context that its a double parameter
        operands = 2;
        precedence = p;
        rightAssoc = a;
        func = f;
    }

    public double evaluate(params double[] values)
    {
        if (values.Length != operands)
            throw new InvalidOperationException("Invalid number of operands");

        //do stuff
        if (operands == 1)
        {
            return ((Func<double, double>)func)(values[0]);
        }
        else
        {
            return ((Func<double, double, double>)func)(values[0], values[1]);
        }
        //more stuff
    }

}
公共类OpWrapper
{
public int操作数;//此运算符需要的操作数。
public int priority;//此运算符在计算时获得的优先级。
public bool rightAssoc;//此运算符是右关联(true)还是左关联(false)。
公共目标函数;
//构造函数初始化所有变量。
公共OpWrapper(int p,Func f,bool a=false)
{
//不需要传入o,我们可以从上下文推断它是一个单独的参数
操作数=1;
优先级=p;
rightAssoc=a;
func=f;
}
//重载构造函数指定正确的方法。
公共OpWrapper(int p,Func f,bool a=false)
{
//不需要传入o,我们可以从上下文推断它是一个双参数
操作数=2;
优先级=p;
rightAssoc=a;
func=f;
}
公共双值求值(参数双[]值)
{
if(values.Length!=操作数)
抛出新的InvalidOperationException(“操作数无效”);
//做事
if(操作数==1)
{
返回((Func)Func)(值[0]);
}
其他的
{
返回((Func)Func)(值[0],值[1]);
}
//更多的东西
}
}
请注意,我从调用中删除了“o”,并且使用了强制转换来选择正确的操作(并检查了num是否正确)