如何根据条件调用不同版本的覆盖方法?
How to call different version of override method based on condition?
我有 1 个 class 库,其中有一些代码可以执行一些 operation.For 实例,它将执行 2 个操作,例如:
- Add
- Multiply
将来我可能会有更多的操作,例如除法。
以上只是一个例子,因为我有一些很长的 运行 操作,每个加法,乘法操作。
所以这个库的想法是接收输入,然后针对这些输入执行长 运行 代码。
这就是我的想法:
public class Input
{
//input properties
}
public interface IOperations
{
public abstract void Process(Input obj);
}
public class Add : IOperations
{
Input obj;
public Add(Input obj)
{
this.obj = obj;
}
public override void Process(Input obj)
{
//Add method implementation
}
}
public class Multiply : IOperations
{
Input obj;
public Multiply(Input obj)
{
this.obj = obj;
}
public override void Process(Input obj)
{
//Multiply method implementation
}
}
现在假设如果我想执行加法运算或乘法运算,那么我将如何根据以下类型调用相应的方法:
string type;
if(type=="Add")
//perform add operation
else if(type=="Multiply")
//perform multiply operation
但是我没有得到正确的方法来设计上述要求的代码结构。
注:创建IOperations
的原因是Interface
是为了dependency injection
好的,正如讨论的那样
为输入和结果定义 类。
public class Input
{
}
public class Result
{
}
定义您的界面
public interface IOperations
{
Result Process(Input obj);
}
定义一个工厂以return所需的实现
public class MathFactory
{
public IOperations GetOperatorByType(string type)
{
switch (type)
{
case "Add":
return new Add(new Input());
case "Multiply":
return new Multiply(new Input());
}
throw new Exception("Unknown type.");
}
}
定义您的具体实现
public class Add : IOperations
{
Input obj;
public Add(Input obj)
{
this.obj = obj;
}
public Result Process(Input obj)
{
//Perform Add here
return new Result();
}
}
public class Multiply : IOperations
{
Input obj;
public Multiply(Input obj)
{
this.obj = obj;
}
public Result Process(Input obj)
{
//Perform multiply here
return new Result();
}
}
终于从代码中调用了。
private void button1_Click(object sender, EventArgs e)
{
var mathFactory = new MathFactory();
var operation = mathFactory.GetOperatorByType("Add");
var result = operation.Process(new Input());
}
显然,您将不得不修改输入对象的使用方式(现在或界面上的构造函数)......以及如何构建结果并将答案公开为 属性。
希望对您有所帮助。
这是 strategy design pattern 的一个很好的候选者。
Define a family of algorithms, encapsulate each one, and make them interchangeable.
接口
public interface IOperation
{
Output Process(Input input);
bool AppliesTo(string operation);
}
public interface IOperationStrategy
{
Output Process(string operation, Input input);
}
运营
public class Add : IOperation
{
public bool AppliesTo(string operation)
{
return nameof(Add).Equals(operation, StringComparison.OrdinalIgnoreCase);
}
public Output Process(Input input)
{
// Implementation
return new Output();
}
}
public class Multiply : IOperation
{
public bool AppliesTo(string operation)
{
return nameof(Multiply).Equals(operation, StringComparison.OrdinalIgnoreCase);
}
public Output Process(Input input)
{
// Implementation
return new Output();
}
}
策略
public class OperationStrategy : IOperationStrategy
{
private readonly IOperation[] operations;
public OperationStrategy(params IOperation[] operations)
{
if (operations == null)
throw new ArgumentNullException(nameof(operations));
this.operations = operations;
}
public Output Process(string operation, Input input)
{
var op = operations.FirstOrDefault(o => o.AppliesTo(operation));
if (op == null)
throw new InvalidOperationException($"{operation} not registered.");
return op.Process(input);
}
}
用法
// I am showing this in code, but you would normally
// do this with your DI container in your composition
// root, and the instance would be created by injecting
// it somewhere.
var strategy = new OperationStrategy(
new Add(), // Inject any dependencies for operation here
new Multiply()); // Inject any dependencies for operation here
// And then once it is injected, you would simply do this.
// Note that it would not be appropriate to use an Enum for
// the operation, because the compiled Enum would have to
// remain in sync with the runtime operation values (not possible).
// That said, the data type doesn't necessarily need to be string.
var input = new Input { Value1 = 2, Value2 = 3 };
var output = strategy.Process("add", input);
// output.Value is 5
var output = strategy.Process("multiply", input);
// output.Value is 6
与工厂设计相比,使用此模式的优势之一是无需更改设计即可添加或删除操作。在工厂设计中,您有一个硬编码到其中的 switch case 语句,每次添加操作时都需要更改它。
当然,如果您为每个 IOperation
使用相同的类型,那么您的输入和输出的设置方式实际上没有任何限制。我只是以这种方式展示它,因为将输出作为 Process
方法的 return 值是明智的,但您使用的实现可能不同。
其他示例
- Best way to use StructureMap to implement Strategy pattern
我有 1 个 class 库,其中有一些代码可以执行一些 operation.For 实例,它将执行 2 个操作,例如:
- Add
- Multiply
将来我可能会有更多的操作,例如除法。
以上只是一个例子,因为我有一些很长的 运行 操作,每个加法,乘法操作。
所以这个库的想法是接收输入,然后针对这些输入执行长 运行 代码。
这就是我的想法:
public class Input
{
//input properties
}
public interface IOperations
{
public abstract void Process(Input obj);
}
public class Add : IOperations
{
Input obj;
public Add(Input obj)
{
this.obj = obj;
}
public override void Process(Input obj)
{
//Add method implementation
}
}
public class Multiply : IOperations
{
Input obj;
public Multiply(Input obj)
{
this.obj = obj;
}
public override void Process(Input obj)
{
//Multiply method implementation
}
}
现在假设如果我想执行加法运算或乘法运算,那么我将如何根据以下类型调用相应的方法:
string type;
if(type=="Add")
//perform add operation
else if(type=="Multiply")
//perform multiply operation
但是我没有得到正确的方法来设计上述要求的代码结构。
注:创建IOperations
的原因是Interface
是为了dependency injection
好的,正如讨论的那样
为输入和结果定义 类。
public class Input
{
}
public class Result
{
}
定义您的界面
public interface IOperations
{
Result Process(Input obj);
}
定义一个工厂以return所需的实现
public class MathFactory
{
public IOperations GetOperatorByType(string type)
{
switch (type)
{
case "Add":
return new Add(new Input());
case "Multiply":
return new Multiply(new Input());
}
throw new Exception("Unknown type.");
}
}
定义您的具体实现
public class Add : IOperations
{
Input obj;
public Add(Input obj)
{
this.obj = obj;
}
public Result Process(Input obj)
{
//Perform Add here
return new Result();
}
}
public class Multiply : IOperations
{
Input obj;
public Multiply(Input obj)
{
this.obj = obj;
}
public Result Process(Input obj)
{
//Perform multiply here
return new Result();
}
}
终于从代码中调用了。
private void button1_Click(object sender, EventArgs e)
{
var mathFactory = new MathFactory();
var operation = mathFactory.GetOperatorByType("Add");
var result = operation.Process(new Input());
}
显然,您将不得不修改输入对象的使用方式(现在或界面上的构造函数)......以及如何构建结果并将答案公开为 属性。
希望对您有所帮助。
这是 strategy design pattern 的一个很好的候选者。
Define a family of algorithms, encapsulate each one, and make them interchangeable.
接口
public interface IOperation
{
Output Process(Input input);
bool AppliesTo(string operation);
}
public interface IOperationStrategy
{
Output Process(string operation, Input input);
}
运营
public class Add : IOperation
{
public bool AppliesTo(string operation)
{
return nameof(Add).Equals(operation, StringComparison.OrdinalIgnoreCase);
}
public Output Process(Input input)
{
// Implementation
return new Output();
}
}
public class Multiply : IOperation
{
public bool AppliesTo(string operation)
{
return nameof(Multiply).Equals(operation, StringComparison.OrdinalIgnoreCase);
}
public Output Process(Input input)
{
// Implementation
return new Output();
}
}
策略
public class OperationStrategy : IOperationStrategy
{
private readonly IOperation[] operations;
public OperationStrategy(params IOperation[] operations)
{
if (operations == null)
throw new ArgumentNullException(nameof(operations));
this.operations = operations;
}
public Output Process(string operation, Input input)
{
var op = operations.FirstOrDefault(o => o.AppliesTo(operation));
if (op == null)
throw new InvalidOperationException($"{operation} not registered.");
return op.Process(input);
}
}
用法
// I am showing this in code, but you would normally
// do this with your DI container in your composition
// root, and the instance would be created by injecting
// it somewhere.
var strategy = new OperationStrategy(
new Add(), // Inject any dependencies for operation here
new Multiply()); // Inject any dependencies for operation here
// And then once it is injected, you would simply do this.
// Note that it would not be appropriate to use an Enum for
// the operation, because the compiled Enum would have to
// remain in sync with the runtime operation values (not possible).
// That said, the data type doesn't necessarily need to be string.
var input = new Input { Value1 = 2, Value2 = 3 };
var output = strategy.Process("add", input);
// output.Value is 5
var output = strategy.Process("multiply", input);
// output.Value is 6
与工厂设计相比,使用此模式的优势之一是无需更改设计即可添加或删除操作。在工厂设计中,您有一个硬编码到其中的 switch case 语句,每次添加操作时都需要更改它。
当然,如果您为每个 IOperation
使用相同的类型,那么您的输入和输出的设置方式实际上没有任何限制。我只是以这种方式展示它,因为将输出作为 Process
方法的 return 值是明智的,但您使用的实现可能不同。
其他示例
- Best way to use StructureMap to implement Strategy pattern