I have a directory full of classes, and they basically all look like this:
class QEDestroy {
void showSettings() {
// Do Something Here
}
}
I then have a class that will instantiate one of the classes based on an item that the user selects:
public class QESettings {
public void GetSettings() {
if (QEActions.actionInt >= 0) {
string action = QEActions.actions[QEActions.actionInt];
// Generate the class based on the action.
// Run showSettings() within the class.
}
}
}
What I can't figure out is how to instantiate the class; for example QEDestroy. From what I have read this is how the class is created:
var myObj = Activator.CreateInstance("", "QE" + action);
If so, how do I run the method showSettings()?
The simplest solution is often the correct one. Create an interface.
public interface QE
{
void showSettings();
}
Then have different "versions" of QE that perform different tasks on the showSettings() function.
public class QE_Example
{
public void override showSettings()
{
print("I am different.");
}
}
Then when you instantiate in your QESettings class you do it like this:
public void GetSettings()
{
if(QEActions.actionInt >= 0)
{
...
QE q = new QE_Example();
q.showSettings();
}
}
This means you have actually stumbled upon a well known Design Pattern named Strategy Pattern.
Related
I don't know the best way to phrase this question in the title, so I apologise if it's not the best.
However I believe the explanation is easy to follow.
I am making a small C# command line shell, and I am implementing each command (e.g. ls, cat) as a separate class. I am using the CommandLineParser library to parse command line options.
Here is my code:
//Command.cs
public abstract class Command<T>
{
public void Run(string[] args)
{
Parser.Default.ParseArguments<T>(args)
.WithParsed(ParseOpts)
.WithNotParsed(HandleParseError);
}
public abstract void ParseOpts(T opts);
public abstract void HandleParseError(IEnumerable<Error> errs);
}
//Cat.cs
public class Cat : Command<CatOptions>
{
//...
public override void ParseOpts(CatOptions opts)
{
//...
}
public override void HandleParseError(IEnumerable<Error> errs)
{
//...
}
//other stuff...
}
//CatOptions.cs
class CatOptions
{
[Option('E', "show-ends", Default = False,
HelpText = "display $ at end of each line")]
public bool ShowEnds { get; set; }
//other options...
}
The way the parser works is that I have to call the boilerplate code that is in Run (i.e. ParseArguments), which will parse the options in args based on the options specified in the options class T. If parsing is successful, it will call ParseOpts, where the command can access the options and do stuff, or HandleParseError if it fails.
I want it so that I don't have to repeat this boilerplate code, but rather just specify the relevant options type T, and implement ParseOpts and HandleParseError as I see fit.
So far, this all makes sense, but I don't know to use it as I want to.
public class Shell
{
//What do I put here?
private Dictionary<String, ???> Commands = new Dictionary<String, ???>
{
{"cat", Cat}, // or new Cat()? typeof(Cat)?
//other commands...
};
//other stuff...
private void Execute()
{
string input = Console.ReadLine();
string[] args = ParseInput(input);
string cmd = args[0];
if (Commands.ContainsKey(cmd))
{
//What I want to be able to do
Commands[cmd].Run(args);
}
else
{
//...
}
}
//...
}
In my main Shell class, I have a Dictionary Commands which I use to map command names to their classes. What I want to be able to do is simply get input from the user, parse the command from the input, check if it's in the dictionary, and then Run that command, but that's where I am stuck.
I can't declare Commands as something like Dictionary<String, Command<T>>, because I have to specify what T is. I don't know if it's possible to somehow declare Commands with a generic generic type or something like that.
I also tried storing the Commands as Type, and then instantiating them at runtime and calling Run; like this:
private Dictionary<String, Type> Commands = new Dictionary<String, Type>
{
{"cat", typeof(Cat)},
//other commands...
};
But I don't know how to instantiate the class and call Run in Execute because I need to somehow cast it to a Command<T> and specify the appropriate T at runtime:
if (Commands.ContainsKey(cmd))
{
//Want to do something like this, but obviously it doesn't work
//because I have to provide the T type
var cmdType = Commands[cmd];
((Command<T>)Activator.CreateInstance(cmdType)).Run(args);
}
At runtime I know that regardless of what class it is they are all of type Command<T>, and I can determine the actual class and type T based on the command name (e.g. cat maps to CatOptions).
I know I can do explicit casting like this with if statements:
if (cmdType == typeof(Cat))
{
((Cat)Activator.CreateInstance(cmdType)).Run(args);
}
else if ...
But I don't want to do that because it will repeat code (unless there's a smart way to do it without repeating code?)
What I want is for Shell to not have to know about any of the *Options classes, and for the *Options classes to all be encapsulated within each respective Command class.
I know it's possible that my design is just terrible and there's a blatantly simple way of doing this; if so please show me.
I know that there must be some way to do it with reflection, but I have been having difficulty figuring out how to do it.
What can I do in order to get the runtime polymorphism that I desire?
Introduce a non generic abstraction
public interface ICommandLine {
void Run(string[] args);
}
that the generic abstraction can be derived from
public abstract class Command<T>: ICommandLine {
public void Run(string[] args) {
Parser.Default.ParseArguments<T>(args)
.WithParsed(ParseOpts)
.WithNotParsed(HandleParseError);
}
protected abstract void ParseOpts(T opts);
protected abstract void HandleParseError(IEnumerable<Error> errs);
}
Allowing for a simpler implementation
//...
private Dictionary<String, ICommandLine> Commands = new Dictionary<String, ICommandLine> {
{"cat", new Cat()},
//other commands...
};
//...
I would add an interface and you can add this instance in dictionary
public interface ICommand
{
void Run(string[] args);
}
//Command.cs
public abstract class Command<T> : ICommand
{
public void Run(string[] args)
{
Parser.Default.ParseArguments<T>(args)
.WithParsed(ParseOpts)
.WithNotParsed(HandleParseError);
}
public abstract void ParseOpts(T opts);
public abstract void HandleParseError(IEnumerable<Error> errs);
}
//Cat.cs
public class Cat : Command<CatOptions>
{
//...
public override void ParseOpts(CatOptions opts)
{
//...
}
public override void HandleParseError(IEnumerable<Error> errs)
{
//...
}
//other stuff...
}
//CatOptions.cs
class CatOptions
{
[Option('E', "show-ends", Default = False,
HelpText = "display $ at end of each line")]
public bool ShowEnds { get; set; }
//other options...
}
I've got a design question.
I've got a static class used in some old code that calls a static method to run some operation. If a certain condition is met, I want to call another method right after it.
I wanted to use the decorator pattern but I can't exactly return an instance of the static class if the condition is not met.
This is what's happening now.
var result = StaticClass.DoSomething(some parameters);
What I want is to write to a database right after that DoSomething is called if another variable is true and I didn't want to just pile on to the old code with conditionals so I'd rather delegate that to some other class. This is what I really want to do.
var result = StaticClassFactory(condition).DoSomething(some parameters);
Class1
void DoSomething(parameters) {
StaticClass.DoSomething()
}
Class2
void DoSomething(parameters) {
StaticClass.DoSomething();
DoSomethignElse();
}
Any suggestions?
What you can do is use an interface to represent the "doer":
public interface IDoer
{
void DoSomething(object parameters);
}
Then create the two classes:
public class DefaultDoer : IDoer
{
public void DoSomething(object parameters)
{
StaticClass.DoSomething(object parameters);
}
}
public class AugmentedDoer : IDoer
{
public void DoSomething(object parameters)
{
StaticClass.DoSomething(object parameters);
DoSomethingElse();
}
}
Then use a factory to return an instance that implements IDoer based on the condition:
public class DoerFactory
{
public IDoer GetDoer(object someCondition)
{
//Determine which instance to create and return it here
}
}
I used placeholders of type object for some things as no more information is available.
2 objects are in this project: Region and Area.
Both objects have a method called
void load();
This is what I want to to, not sure if it's possible:
Invoke the same Detail function with similar implementation depending on which object called the function.
The Detail function will do something like this:
void Detail(parameter)
{
object_name.load();
}
I didn't want to write 2 overloaded functions for the each object because then I would have 2 functions with nearly identical implementations.
I have tried:
void Detail(string land)
{
if(land=="region")
{
Region land = new Region();
}
else if(land=="area")
{
Area land = new Area();
}
land.load();
}
But this doesn't work because land.load() will cause an error since the function cannot determine at definition whether land will be a Region or an Area object.
It sounds like you want an interface.
public interface IShape
{
void load();
}
Which both Region and Area would implement:
public class Region : IShape
{
public void load() { /* Region Implementation */ }
}
public class Area : IShape
{
public void load() { /* Area Implementation */ }
}
Your detail function now looks like this:
void Detail(IShape shape)
{
shape.load();
}
Some notes:
Interfaces define a contract without implementation. Your Detail function does not need to know whether it is an Area or a Region provided the class in question adheres to the contract that IShape defines, that is - it has a load() method.
Edit
Looking at your question more closely, it also looks like you want to implement a factory. So let's do that also.
public static class ShapeFactory
{
private static Dictionary<string, Func<IShape>> _shapes = new Dictionary<string, Func<IShape>>();
static ShapeFactory()
{
// Register some creators:
_shapes.Add("region", () => return new Region());
_shapes.Add("area", () => return new Area());
}
public static IShape Create(string shape)
{
return _shapes[shape]();
}
}
This allows your detail function to be rather simple:
void Detail(string shape)
{
ShapeFactory.Create(shape).load();
}
Error checking omitted for brevity. So what does this do? Well, a factory is - well - a factory. We create a dictionary (keyed by name), and whose value is a function that returns an IShape.. we can now dynamically create shapes by name and call the load method on it.
Edit 2
Given your comment that you cannot change what interfaces these classes implement, there's no reason we can't still obfuscate the load method (given that they both implement it). All we have to do is, once again utilise our interface again:
public interface IShapeWrapper
{
void load();
}
Note that our interface is still the same. What is different is the implementations:
public class RegionWrapper : IShapeWrapper
{
private Region _region;
public RegionWrapper()
{
_region = new Region();
}
public void load()
{
_region.load();
}
}
public class AreaWrapper : IShapeWrapper
{
private Area _area;
public AreaWrapper()
{
_area = new Area();
}
public void load()
{
_area.load();
}
}
The factory remains much the same, with the exception that it takes the wrapper classes rather than the Area/Region ones.
You might want to make the classes share an interface, e.g.
public interface ILoad { void Load(); }
public class Area : ILoad { }
public class Region : ILoad { }
void Detail(ILoad land)
{
land.Load();
}
Or maybe use dynamic, e.g.
void Detail(string landStr)
{
dynamic land;
if (landStr == "region")
{
land = new Region();
}
else
{
land = new Area();
}
land.load();
}
There are several ways of addressing this. A simple way would be giving both Area and Region classes an ILoadable interface to implement, like this:
interface ILoadable {
void load();
}
class Area : ILoadable {
public void load() {...}
}
class Region : ILoadable {
public void load() {...}
}
Now you can change your Detail method as follows:
void Detail(string land) {
ILoadable loadable;
if(land=="region") {
loadable = new Region();
} else if(land=="area") {
loadable = new Area();
} else {
throw new InvalidOperationException(land);
}
loadable.load();
}
If you would like to make Detail a generic function, you can get rid of the string land parameter, and pass the class directly:
void Detail<T>() where T : ILoadable, new() {
new T().load();
}
You can call this function like this:
Detail<Region>();
Detail<Area>();
Going the interface way is quite a possibility, or creating a full fledged Factory also, but it might be overkill depending on your need.
If you expect to have a lot more functions like load(), do it the way other have said, but if not, or if you cannot change what class they inherit like you stated, here is another way of doing it simply and quickly using dynamics:
void Detail(string land)
{
dynamic land = null;
if (land == "region")
{
land = new Region();
}
else if (land == "area")
{
land = new Area();
}
else
{
// Not what we expected
throw new ArgumentException("land: " + land);
}
try
{
land.load();
}
catch (RuntimeBinderException ex)
{
// .load() does not exist
}
}
Maybe overloading a method is not exactly what is necessary but this is the best i could come up with.
I have a class:
public class Worker {
private string jobType;
public Worker(string jt)
{
this.jobType = jt;
}
public void ProcessJob()
{
if(jobType.Equals("Pizza") MakePizza();
else if (jobType.Equals("Burger") MakeBurger();
}
private void MakePizza()
{
// make pizza
}
private void MakeBurger()
{
// make burger
}
}
The above is just an example of illustration. When the class is constructed, it is constructed with a specific job type, and that won't change. However it may need to perform millions of jobs, always of the same type. The ProcessJob() will be called all the time, but the caller won't know what type of worker this is. I would like to avoid running the if check every single time, there has to be a way to do that check only once and prep it.
In my case, making child classes (pizza worker, burger worker, etc.) is not an option, as in my real case, the class is large and there is only one tiny difference. Changing it will impact the whole architecture so it needs to be avoided.
Create an abstract base class, which contains common things a worker can do. Then declare derived classes for specialized workers.
public abstract class Worker
{
public abstract void ProcessJob();
}
public class PizzaWorker : Worker
{
public override void ProcessJob()
{
// Make pizza
}
}
public class BurgerWorker : Worker
{
public override void ProcessJob()
{
// Make burger
}
}
Now you can create workers of different types and let them do their job:
var workers = new List<Worker>();
workers.Add(new PizzaWorker());
workers.Add(new BurgerWorker());
foreach (Worker worker in workers) {
woker.ProcessJob();
}
This will automatically call the right implementation of ProcessJob for each type of worker.
Note: If-else-if cascades and switch statements are often an indication that the code works in a procedural rather than object-oriented way. Refactor it to be object-oriented!
You could use a delegate created when the object is constructed, this way the dispatch is done automatically:
public class Worker
{
private delegate void MakeSomething();
private MakeSomething makeWhat;
private string jobType;
public Worker(string jt)
{
this.jobType = jt;
switch (jt)
{
case "Pizza":
makeWhat = new MakeSomething(MakePizza);
break;
case "Burger":
makeWhat = new MakeSomething(MakeBurger);
break;
default:
throw new ArgumentException();
}
}
public void ProcessJob()
{
makeWhat();
}
private void MakePizza()
{
//make pizza
}
private void MakeBurger()
{
//make burger
}
}
I would still recommend to use sub classes. If you cannot inherit from Worker then create new class hierarchy that is used inside the worker. This way anyone using Worker class doesn't have to know that there are sub classes. If you really really hate sub classes or you have some other reason you don't want them you can use dictionary. It contains job type as key and Action as the method it calls. If you need more jobs just create the private method and register it in the RegisterWorkers method.
private Dictionary<string, Action> actions = new Dictionary<string, Action>();
public Worker(string jt)
{
this.jobType = jt;
this.RegisterWorkers();
}
private void RegisterWorkers
{
this.actions["Pizza"] = this.MakePizza;
this.actions["Burger"] = this.MakeBurger;
}
public void ProcessJob()
{
var action = this.actions[this.jobType];
action();
}
No, I don't think it should be avoided. Any common functionality should go in a base class. I think you need a static factory method, that returns a child class based on the string parameter.
public abstract class Worker {
public virtual void ProcessJob();
public static Worker GetWorker(string jobType) {
if(jobType.Equals("Pizza")
return new PizzaWorker();
else if (jobType.Equals("Burger")
return new BurgerWorker();
else
throw new ArgumentException();
}
// Other common functionality
protected int getFoo() {
return 42;
}
}
public class PizzaWorker : Worker {
public override void ProcessJob() {
// Make pizza
int y = getFoo() / 2;
}
}
public class BurgerWorker : Worker {
public override void ProcessJob() {
// Make burger
int x = getFoo();
}
}
So to use this:
Worker w = Worker.GetWorker("Pizza");
w.ProcessJob(); // A pizza is made.
This is exactly why there are patterns: Command, Strategy, Decorator.
I believe the command pattern is what you are looking for. First you have a basic 'command' template:
public interface IJob {
void ProcessJob();
}
Different jobs would then be performed as follows:
public class MakePizza : IJob {
// implement the interface
public void ProcessJob() {
// make a pizza
}
}
Now, you could have a JobFactory as follows:
public static class JobFactory {
public static IJob GetJob(string jobType) {
if(jobType.Equals("Pizza"){
return new MakePizza();
} else (jobType.Equals("Burger") {
return new MakeBurger();
}
// to add jobs, extend this if-else-if or convert to switch-case
}
}
Worker can now look like this:
public class Worker {
private IJob job;
public Worker(string jt) {
job = JobFactory.GetJob(jt);
}
public void ProcessJob() {
job.ProcessJob();
}
}
If you don't have access to code to make these changes, then another pattern you may want to look into is the Adapter.
You're talking about basic inheritance here. There are a couple of ways that you could do this.
Make a Base Class that is
public class Job
{
virtual void ProcessJob();
}
Then a MakePizza class
public class MakePizza : Job
{
public void ProcessJob()
{
//make Pizza
}
}
Then in your worker class instead of having a JobType as a string which will lead to all kinds of potential bugs.
public class Worker{
private Job jobType;
public Worker(Job jt){
this.jobType = jt;
}
public void ProcessJob()
{
Job.ProcessJob();
}
}
If you have to pass through a string you could simply load up the JobType through reflection, throwing a error if the type doesn't exist.
having to change other classes means you need to change code, not that you need to change architecture. the best answer is just to change the code. in the long term, the maintenance burden of having to write this in a less-than-ideal fashion will cost you more than just changing the code. use inheritance and bite the bullet on making the change now. if you have iterators that will have problems with dealing with subtypes, your iterators are doing more than being iterators, and you are better off fixing that than going forward with them. if the other classes care about what subtype of worker they are dealing with, that's a problem in and of itself that you should fix. ultimately, the dependent code should not care which type of worker it is. that's really what you are after anyway. the instance of a type that has work as its base type is still a worker and that is all the class using a worker should care about.
I have a class that gets used in a client application and in a server application.
In the server application, I add some functionality to the class trough extension methods. Works great. Now I want a bit more:
My class (B) inherits from another class (A).
I'd like to attach a virtual function to A (let's say Execute() ), and then implement that function in B. But only in the server. The Execute() method would need to do stuff that is only possible to do on the server, using types that only the server knows about.
There are many types that inherit from A just like B does, and I'd like to implement Execute() for each of them.
I was hoping I could add a virtual extension method to A, but that idea doesn't seem to fly. I'm looking for the most elegant way to solve this problem, with or without extension methods.
No, there aren't such things as virtual extension methods. You could use overloading, but that doesn't support polymorphism. It sounds like you might want to look at something like dependency injection (etc) to have different code (dependencies) added in different environments - and use it in regular virtual methods:
class B {
public B(ISomeUtility util) {
// store util
}
public override void Execute() {
if(util != null) util.Foo();
}
}
Then use a DI framework to provide a server-specific ISomeUtility implementation to B at runtime. You can do the same thing with a central static registry (IOC, but no DI):
override void Execute() {
ISomeUtility util = Registry.Get<ISomeUtility>();
if(util != null) util.Foo();
}
(where you'd need to write Registry etc; plus on the server, register the ISomeUtility implementation)
You can use the new dynamic type functionality to avoid having to build a registry of types to methods:
using System;
using System.Collections.Generic;
using System.Linq;
using visitor.Extension;
namespace visitor
{
namespace Extension
{
static class Extension
{
public static void RunVisitor(this IThing thing, IThingOperation thingOperation)
{
thingOperation.Visit((dynamic)thing);
}
public static ITransformedThing GetTransformedThing(this IThing thing, int arg)
{
var x = new GetTransformedThing {Arg = arg};
thing.RunVisitor(x);
return x.Result;
}
}
}
interface IThingOperation
{
void Visit(IThing iThing);
void Visit(AThing aThing);
void Visit(BThing bThing);
void Visit(CThing cThing);
void Visit(DThing dThing);
}
interface ITransformedThing { }
class ATransformedThing : ITransformedThing { public ATransformedThing(AThing aThing, int arg) { } }
class BTransformedThing : ITransformedThing { public BTransformedThing(BThing bThing, int arg) { } }
class CTransformedThing : ITransformedThing { public CTransformedThing(CThing cThing, int arg) { } }
class DTransformedThing : ITransformedThing { public DTransformedThing(DThing dThing, int arg) { } }
class GetTransformedThing : IThingOperation
{
public int Arg { get; set; }
public ITransformedThing Result { get; private set; }
public void Visit(IThing iThing) { Result = null; }
public void Visit(AThing aThing) { Result = new ATransformedThing(aThing, Arg); }
public void Visit(BThing bThing) { Result = new BTransformedThing(bThing, Arg); }
public void Visit(CThing cThing) { Result = new CTransformedThing(cThing, Arg); }
public void Visit(DThing dThing) { Result = new DTransformedThing(dThing, Arg); }
}
interface IThing {}
class Thing : IThing {}
class AThing : Thing {}
class BThing : Thing {}
class CThing : Thing {}
class DThing : Thing {}
class EThing : Thing { }
class Program
{
static void Main(string[] args)
{
var things = new List<IThing> { new AThing(), new BThing(), new CThing(), new DThing(), new EThing() };
var transformedThings = things.Select(thing => thing.GetTransformedThing(4)).Where(transformedThing => transformedThing != null).ToList();
foreach (var transformedThing in transformedThings)
{
Console.WriteLine(transformedThing.GetType().ToString());
}
}
}
}
I would suggest something like the following. This code could be improved by adding support for detecting intermediate class hierarchy types that don't have a dispatch mapping and calling the nearest dispatch method based on the runtime hierarchy. It could also be improved by using reflection to detect overload of ExecuteInteral() and adding them automatically to the dispatch map.
using System;
using System.Collections.Generic;
namespace LanguageTests2
{
public class A { }
public class B : A {}
public class C : B {}
public static class VirtualExtensionMethods
{
private static readonly IDictionary<Type,Action<A>> _dispatchMap
= new Dictionary<Type, Action<A>>();
static VirtualExtensionMethods()
{
_dispatchMap[typeof(A)] = x => ExecuteInternal( (A)x );
_dispatchMap[typeof(B)] = x => ExecuteInternal( (B)x );
_dispatchMap[typeof(C)] = x => ExecuteInternal( (C)x );
}
public static void Execute( this A instance )
{
_dispatchMap[instance.GetType()]( instance );
}
private static void ExecuteInternal( A instance )
{
Console.WriteLine("\nCalled ToString() on: " + instance);
}
private static void ExecuteInternal(B instance)
{
Console.WriteLine( "\nCalled ToString() on: " + instance );
}
private static void ExecuteInternal(C instance)
{
Console.WriteLine("\nCalled ToString() on: " + instance);
}
}
public class VirtualExtensionsTest
{
public static void Main()
{
var instanceA = new A();
var instanceB = new B();
var instanceC = new C();
instanceA.Execute();
instanceB.Execute();
instanceC.Execute();
}
}
}
Virtual implies inheritance in a OOP way and extension methods are "just" static methods that through a bit a syntactic sugar the compiler allows you to pretend to call on an instance of the type of its first parameter. So no, virtual extension methods are out of the question.
Check out the answer by Marc Gravell for a possible solution to your problem.
You can implement a service register. Example (server side):
static IDictionary<Type, IService> serviceRegister;
public void ServerMethod(IBusinessType object)
{
serviceRegister[obect.GetType()].Execute(object);
}
What you need are rather services in your server, which implement server side functionality, instead of extension methods. I wouldn't put to much logic into extension methods.
Let me check: you have a class hierarchy inheriting from A, presumably structured according to your business domain. Then you want to add behaviours depending on where the classes execute. So far you've used extension methods, but now you find you cannot get them to vary with your class hierarchy. What kinds of behaviours are you attaching at the server?
If it's stuff like transaction management and security, policies implemented through dependency injection à la Marc's suggestion should work well. You could also consider implementing the Strategy pattern through delegates and lambdas, for a more limited version of DI. However, what's not clear is how client code currently uses your classes and their extension methods on the server. How dependent are other classes on how you add the server-side functionality? Are they server-side only classes that currently expect to find the extension methods?
In any case, it sounds like you're going to need a careful testability design and testing strategy since you are introducing variation along two simultaneous dimensions (inheritance hierarchy, execution environment). You are using unit testing, I trust? Check that whatever solution you choose (e.g. DI through configuration) interacts well with testing and mocking.