C#中的委托函数问题?
我正在学习C#,我感兴趣的领域之一是委托函数。下面的代码使用它们将函数应用于[start,limit]范围内的每个数字,然后再求和。为了清楚起见,这是一个相当简单的示例C#中的委托函数问题?,c#,delegates,C#,Delegates,我正在学习C#,我感兴趣的领域之一是委托函数。下面的代码使用它们将函数应用于[start,limit]范围内的每个数字,然后再求和。为了清楚起见,这是一个相当简单的示例 // function passing a delegate function public override void solveProblem() { int squareOfSum = (int) Math.Pow(Library.Math.sumRange(1, 101), 2); int sumOfSq
// function passing a delegate function
public override void solveProblem() {
int squareOfSum = (int) Math.Pow(Library.Math.sumRange(1, 101), 2);
int sumOfSquares = Library.Math.sumRange(1, 101, new Func<double, double, double>(Math.Pow), 2);
this.solution = (squareOfSum - sumOfSquares).ToString();
}
// function that accepts / uses delegate function
static public int sumRange(int start, int limit, Delegate operation, params object[] args) {
int sum = 0;
for (int current = start; current < limit; current++) {
// add the current number in the range as an arguement
object[] newArgs = new object[args.Length + 1];
newArgs[0] = current;
args.CopyTo(newArgs, 1);
// sum the result of the operation (delegate function)
sum += Convert.ToInt32(operation.DynamicInvoke(newArgs));
}
return sum;
}
//传递委托函数的函数
公共覆盖无效解决方案问题(){
intsquareofsum=(int)Math.Pow(Library.Math.sumRange(1101),2);
int-sumOfSquares=Library.Math.sumRange(1011,新函数(Math.Pow),2);
this.solution=(平方和-平方和).ToString();
}
//接受/使用委托函数的函数
静态公共int-sumRange(int-start、int-limit、委托操作、params-object[]args){
整数和=0;
用于(int current=start;current
我的具体问题是:
- 是否可以使用动态委托函数(接受具有未知类型的可变长度参数列表)但强制委托函数返回特定类型?对于非动态委托函数,您可以设置返回类型,但还必须设置参数数量及其类型
- 使用DynamicVoke比使用非动态委托函数慢多少
- 处理参数的最佳方法是什么(即接受其他参数的列表,并在使用委托的函数需要添加的任何参数之前添加)
- 我是否需要声明'new Func(Math.Pow)'来传递幂函数,或者是否有方法只传递Math.Pow(并隐式传递返回类型和参数)
DynamicInvoke
调用动态委托,然后将返回值强制转换为您知道的委托返回的内容(或者将其保留为对象
)。我说“您知道您的委托返回的内容”但实际情况有点复杂:对于值类型,您必须将返回值强制转换为用作返回值的类型,否则将得到InvalidCastException
。对于引用类型,您可以使用返回对象的接口或基类(可为null的类型除外)
使用DynamicVoke比使用非动态委托函数慢多少
我已经测试了一个voiddo()
方法(可能是最简单的方法,没有参数装箱),时间差很小,比如说400x:-)在70x和150x之间
我是否需要声明'new Func(Math.Pow)'来传递幂函数,或者是否有方法只传递Math.Pow(并隐式传递返回类型和参数)
创建新的Func
/Action
委托是正确的路径
通常,正确的解决方案不是您正在做的事情。正确的解决方案是像LINQ那样做。例如:
int pow = 2;
Func<int, int> myFunc = p => (int)Math.Pow(p, pow);
var listOfNumbers = Enumerable.Range(1, 100);
var result = listOfNumbers.Sum(p => myFunc(p));
int-pow=2;
Func myFunc=p=>(int)Math.Pow(p,Pow);
var listOfNumbers=可枚举范围(1100);
var result=listOfNumbers.Sum(p=>myFunc(p));
现在,您有了一个委托(
myFunc
),它接受一个数字并返回该数字的平方(注意,通过“closures”它在pow
)附近关闭)(如果您不知道闭包是什么,请尝试将该单词与lambda函数放在谷歌中)。将数字列表作为一个IEnumerable
,您可以通过LINQ上读取的myFunc
对这些数字进行“转换”求和-使用IEnumerable生成更紧凑的代码
也就是说,Enumerable.Range()和Enumerable.Aggregate()的组合正是您试图实现的目标:
var sum = Enumerable.Range(start,limit).Aggregate((s, cur)=> s+cur);
var sumSq = Enumerable.Range(start,limit).Aggregate((s, cur)=> s+ cur * cur);
lucisferre对动态类型有很好的理解。C#主要是一种静态类型的语言。尝试在任何地方使用动态功能都会是一种痛苦的经历。这非常有趣。我使用它主要是为了探索/了解委托函数,但感谢您给我提供了C#的另一个方面来了解!