次のクラスのアーキテクチャを考えると、実行可能なコードを引数として渡すことが非常に役立つことを理解しています。 これにより、一連のifやcaseを回避し、コードをよりエレガントにすることができます。 エヘム...私は夢中になったもの。
では、これはC#でどのように行われますか? たとえば、電卓を作成し、最も単純なロジックがあるとします。
public double PerformOperation(string op, double x, double y) { switch (op) { case "+": return x + y; case "-": return x - y; case "*": return x * y; case "/": return x / y; default: throw new ArgumentException(string.Format("Operation {0} is invalid", op), "op"); } }
, :
- . . .
- . , switch .
?
:
switch (op) { case "+": return this.DoAddition(x, y); case "-": return this.DoSubtraction(x, y); case "*": return this.DoMultiplication(x, y); case "/": return this.DoDivision(x, y); default: throw new ArgumentException(string.Format("Operation {0} is invalid", op), "op"); } ... private double DoDivision(double x, double y) { return x / y; } private double DoMultiplication(double x, double y) { return x * y; } private double DoSubtraction(double x, double y) { return x - y; } private double DoAddition(double x, double y) { return x + y; }
:
private delegate double OperationDelegate(double x, double y); private Dictionary<string, OperationDelegate> _operations; public Calculator() { _operations = new Dictionary<string, OperationDelegate> { { "+", this.DoAddition }, { "-", this.DoSubtraction }, { "*", this.DoMultiplication }, { "/", this.DoDivision }, }; } public double PerformOperation(string op, double x, double y) { if (!_operations.ContainsKey(op)) throw new ArgumentException(string.Format("Operation {0} is invalid", op), "op"); return _operations[op](x, y); }
? — .
private delegate double OperationDelegate(double x, double y); private Dictionary<string, OperationDelegate> _operations;
. , . double double. (+-*/) .
: .
,
{ "+", this.DoAddition }
case "+": return x + y;
C# 2.0 :
{ "+", delegate(double x, double y) { return x + y; } }, { "-", delegate(double x, double y) { return x - y; } }, { "*", this.DoMultiplication }, { "/", this.DoDivision },
, . ...
C# 3.0 :
private Dictionary<string, Func<double, double, double>> _operations = new Dictionary<string, Func<double, double, double>> { { "+", (x, y) => x + y }, { "-", (x, y) => x - y }, { "*", this.DoMultiplication }, { "/", this.DoDivision }, };
--, — !
Func<double, double, double> delegate double Delegate(double x, double y)
Func< , , >. Func , . , Func , , . ?
? PerformOperation .
public double PerformOperation(string op, double x, double y) { if (!_operations.ContainsKey(op)) throw new ArgumentException(string.Format("Operation {0} is invalid", op), "op"); return _operations[op](x, y); }
operations . xml-, , .
Func<double, double, double>
.
C# , .
JavaScript
var operations = { "+": function(x, y) { return x + y; } };
-?
: C# - , . , . .
, .
PerformOperation . DefineOperation Calculator:
public void DefineOperation(string op, Func<double, double, double> body) { if (_operations.ContainsKey(op)) throw new ArgumentException(string.Format("Operation {0} already exists", op), "op"); _operations.Add(op, body); }
:
var calc = new Calculator(); calc.DefineOperation("mod", (x, y) => x % y); var mod = calc.PerformOperation("mod", 3.0, 2.0); Assert.AreEqual(1.0, mod);
PerformOperation switch.