imagine you have the following interfaces:
public interface IInterfaceA : IInterfaceX
{
//
// declarations
//
}
public interface IInterfaceB : IInterfaceX
{
//
// declarations
//
}
public interface IInterfaceC : IInterfaceX
{
//
// declarations
//
}
Now I want to replace the following three methods which perform almost the same with a single function:
class SomeClass
{
IInterfaceA myVarA;
IInterfaceB myVarB;
IInterfaceC myVarC;
void SomeMethodA(IInterfaceX someVarX)
{
myVarA = (IInterfaceA)someVarX;
}
void SomeMethodB(IInterfaceX someVarX)
{
myVarB = (IInterfaceB)someVarX;
}
void SomeMethodC(IInterfaceX someVarX)
{
myVarC = (IInterfaceC)someVarX;
}
}
I thought about something like:
void SomeMethod(IInterfaceX targetVar, IInterfaceX someVarX)
{
//
// here's my problem
//
targetVar = (CastIDontKnowHowToPerform)someVarX;
}
which is used sth. like
SomeMethod(myVarA, someVarX);
SomeMethod(myVarB, someVarX);
SomeMethod(myVarC, someVarX);
So my questions are:
Is it possible what I want to get?
How to perform this cast I don't know how to perform?
Perhaps a design pattern is more appropriate
I'm just looking for the best way to refactor those three functions by replacing them by a single one.
Things I've tried so far:
I used things like object.GetType() and object.GetType().GetInterfaces() which works well to get the type of an object or its interface(s) but none to set the type of an object to its interface.
Hope you can help me...
Regards,
Inno
[EDIT]
Ah, damn it... after clicking "Ask your question" and having a short look at it this seems to a be typical case for a generic function (or a template in C++-term).
[/EDIT]
void SomeMethod<T>(out T targetVar, IInterfaceX someVarX) where T: IInterfaceX
{
targetVar = (T) someVarX;
}
One possibility is the "is" operator:
void SomeMethod(IInterfaceX someVarX)
{
if (someVarX is IInterfaceA)
SomeMethodA((IInterfaceA)someVarX);
else if (...
}
A better method would be to put the operation into the IInterfaceX to avoid casting altogether:
void SomeMethod(IInterfaceX someVarX)
{
someVarX.SomeMethod();
}
Related
I have the following function in c#:
bool Handle<TCommandHandler, TModel>(TModel model) where TCommandHandler : ICommandHandler<TModel> {
// ...
_container.Resolve<TCommandHandler>();
// ...
}
Since TModel is clear from a function parameter I want some way to not specify its type when calling a function. Ideally I want to call it like:
Handle<MyCommandHandler>(model);
Since this is probably impossible, I came up with the following:
HandleTemp<TModel> Handle<TModel>(TModel model) {
return new HandleTemp<TModel>(model);
}
public class HandleTemp<TModel> {
private TModel _model;
public HandleTemp(TModel model) { _model = model;}
public bool With<TCommandHandler>() where TCommandHandler : ICommandHandler<TModel> {
}
}
So I'm now calling it like:
Handle(model).With<MyCommandHandler>();
Are there other possibilities? Did I make something completely wrong with my solution?
No, your analysis and solution look about right. Indeed, generic type inference can work only on an all-or-nothing basis. If there are some generic parameters that can't be inferred, all must be explicitly stated. Personally I'd quite like a way to say "you worry about these parameters, I'll tell you this one", but... that doesn't exist.
The only other option is to add an artificial extra regular parameter to allow it to infer the generic parameter - a bit yucky.
One other option: challenge the assumption that generics are needed here. For example, could it just be a Type instance? Would:
bool Handle<TModel>(TModel model, Type type)...
...
Handle(model, typeof(MyCommandHandler));
work, for example? I can't answer this directly, as I don't know the particulars of your _container.Resolve<TCommandHandler>(); method, as to whether that could be adjusted to take a Type rather than a <T>.
All the C# compiler needs is a demonstration of the type in the arguments, so instead of attempting to place it in the generic arguments (at the usage site) make something that lets you provide an argument that helps the compiler identify that type. To make it less confusing, here is an example:
// Your classes/interfaces.
class Container
{
public static T Resolve<T>()
{
Console.WriteLine("Resolving {0}", typeof(T).FullName);
return default(T);
}
}
interface ICommandHandler<TModel>
{
void DoSomething();
}
// An implemented ICommandHandler.
public class WackyCommandHandler : ICommandHandler<string>
{
public void DoSomething() { }
}
// Used to help the C# compiler identify types.
public static class Identify
{
public static TypeIdentity<TType> TheType<TType>()
{
return null; // You don't actually need an instance.
}
}
public sealed class TypeIdentity<TType>
{
private TypeIdentity() { }
}
// Your method
static bool Handle<TCommandHandler, TModel>(TModel model, TypeIdentity<TCommandHandler> handler)
where TCommandHandler : ICommandHandler<TModel>
{
var item = Container.Resolve<TCommandHandler>();
return true;
}
// And the usage site:
var a = "hello";
Handle(a, Identify.TheType<WackyCommandHandler>());
Console.ReadLine();
How to write better?
public void Foo(bool isStart) {
// Code [Common]
if (is Start) {
// Code [Start]
} else {
// Code [End]
}
// Code [Common]
}
or
public enum MyEnum {
Start, End
}
public void Foo(MyEnum param) {
// Code [Common]
switch (param) {
case MyEnum.Start:
// Code [Start]
break;
case MyEnum.End:
// Code [End]
break;
}
// Code [Common]
}
Update: I'm looking for a small solution. "Common", "Start" and "End" parts are very short, I do not want to split Foo into several methods.
How about:
public class Foo
{
public void Start()
{
PreCommon();
// Code [Start]
PostCommon();
}
public void Stop()
{
PreCommon();
// Code [Stop]
PostCommon();
}
private void PreCommon()
{
// Code [Pre-Common]
}
private void PostCommon()
{
// Code [Post-Common]
}
...
}
Methods that have a single responsibility are easier to read, easier to understand and easier to maintain.
it just depends on the situation and your approach. for instance YAGNI says you aren't going to need the enum so might as well stick with the bool. but then again if you know you are going to need it, or think you may, then probably the second is the way to go. OR, really if you are going for something that's more expressive, i like the second way better because it makes it obvious to the caller what is being set; true/false is not nearly as descriptive as MyEnum.Start and MyEnum.Stop.
I'm not sure what would be best, it would depend on a number of factors but using an enum in place of a bool like you did here is not the way to go.
Here's another option. Works well if you have more than two cases of code to work with (if that was your point of the enum).
public void Foo(Action unique)
{
// Code [Common]
unique();
// Code [Common]
}
private void StartCode()
{
// Code [Start]
}
private void EndCode()
{
// Code [End]
}
// call it
Foo(StartCode);
My rule of thumb is to take a few minutes when I get to this situation, and really think about if I can make a justification in future scenarios or versions for a 3rd case (necessitating an enumeration or completely new type). If I cannot think of a 3rd case, I always go with bool because they're just easier to test.
I always name on the positive side of things and begin the propertyname with a form of 'to be'... such as "IsActive" or "HasChildren"
How about this ↓
abstract class FooBase
{
public abstract void DoSomthingBegin();
public abstract void DoSomthingEnd();
public void Foo()
{
// Code [Common]
DoSomthingBegin();
DoSomthingEnd();
// Code [Common]
}
}
class FooBegin : FooBase
{
public override void DoSomthingBegin()
{
Console.WriteLine("OnBegin");
}
}
class FooEnd : FooBase
{
public override void DoSomthingBegin()
{
Console.WriteLine("OnEnd");
}
}
I am trying to decide the best way to structure some code. I will admit this may be overboard and is turning into something more academic than practical. Sometimes you just cannot help yourself.
Let me contrive a simple example:
Suppose you have classes/interfaces such as:
interface IProcessedPhoto { }
interface IPhotoProcessor
{
IProcessedPhoto Process(byte[] bytes);
void Alter(IProcessedPhoto processedPhoto);
}
class PhotoProcessedWithAMethod : IProcessedPhoto { }
class PhotoProcessedWithBMethod : IProcessedPhoto { }
class AProcessor : IPhotoProcessor
{
IProcessedPhoto Process(byte[] bytes); // Returns PhotoProcessedWithAMethod
void Alter(IProcessedPhoto processedPhoto)
{
var casted = processedPhoto as PhotoProcessedWithAMethod;
// a "B" would crash here.
}
}
class BProcessor : IPhotoProcessor
{
IProcessedPhoto Process(byte[] bytes); // Returns PhotoProcessedWithBMethod
void Alter(IProcessedPhoto processedPhoto)
{
var casted = processedPhoto as PhotoProcessedWithBMethod;
// an "A" would crash here.
}
}
class Algorithm
{
void DoStuff()
{
var processor = ProcessorFactory.CreateProcessor(//stuff);
var processedPhoto = processor.ProcessPhoto(new byte[100]);
processor.Alter(processedPhoto);
}
}
So basically I want the DoStuff() method to create one kind of image processor, and call the appropriate Process method. However, despite what the interface suggests, Process only works on an IProcessedPhoto of the appropriate type (A and B photos are NOT interchangeable, they just have similar method names). My real code is more complicated in that each processor has several classes specific to them and not interchangeable, but I want to perform the same set of "logical" operations like a template method.
var artifactA = processor.DoA();
var artifactB = processor.DoB();
var final = processor.Process(artifactA, artifactB);
I hope that explains it.
You can use generics to bind the specific implementation of IProcessedPhoto to your IPhotoProcessors:
interface IPhotoProcessor<TProcessedPhoto>
where TProcessedPhoto: IProcessedPhoto {
TProcessedPhoto Process(byte[] bytes);
void Alter(TProcessedPhoto processedPhoto);
}
...
class AProcessor : IPhotoProcessor<PhotoProcessedWithAMethod> { ... }
class BProcessor : IPhotoProcessor<PhotoProcessedWithBMethod> { ... }
The downside is that your factory also needs this information:
ProcessorFactory.CreateProcessor<PhotoProcessedWithAMethod>(/*stuff*/);
It seems to me that your IProcessedPhoto/IPhotoProcessor abstraction is too generalized, at least for the purposes you describe.
You could create derived interfaces for each of the photo classes and processors (e.g. IProcessedPhotoA/IPhotoProcessorA, and same for B), and adjust your code so that only those photos that implement the required interface (A or B) are passed to a given processor.
I'm not sure whether that's the best solution for your entire codebase (which I can't see). My suggestion is based on this bit of your post:
However, despite what the interface suggests, Process only works on an IProcessedPhoto of the appropriate type (A and B photos are NOT interchangeable, they just have similar method names)
If they're not interchangeable for the purpose of being used by a PhotoProcessor, your code shouldn't treat them as such.
I would be tempted to put the Alter method on the IProcessedPhoto interface, then return an implementation that can correctly alter the processed photo. Note you could connect it to the processor as well and use methods from it if needed (not shown).
public enum PhotoProcessingMethod { A, B }
public interface IProcessedPhoto
{
void Alter();
}
public AProcessedPhoto : IProcessedPhoto
{
...
public void Alter()
{
... alter an A...
}
}
public BProcessedPhoto : IProcessedPhoto
{
...
public void Alter()
{
... alter a B...
}
}
public interface IPhotoProcessor
{
IProcessedPhoto Process(byte[] bytes, PhotoProcessingMethod method);
}
public class PhotoProcessor : IPhotoProcessor
{
public IProcessedPhoto Process(byte[] bytes, PhotoProcessingMethod method)
{
IProcessedPhoto photo;
switch (method)
{
case PhotoProcessingMethod.A:
photo = new AProcessedPhoto(bytes);
break;
case PhotoProcessingMethod.B:
photo = new BProcessedPhoto(bytes);
break;
}
...
return photo;
}
}
Used as:
var processor = new PhotoProcessor();
var photoA = processor.Process( bytes, PhotoProcessingMethod.A );
photoA.Alter();
I currently have method which is trying to find out what the obj is it recieved. It knows is on a certain interface, for example IService but I have code which looks at it and tries to tell me is it is for example Service1 or Service2.
I currently a lot of if(obj is thisObj) style statements, what would be the best solution to make this code pretty?
here is a sample of what exactly I have:
public void DoSomething(IService service)
{
if (service is Service1)
{
//DO something
}
if (service is Service2)
{
//DO something else
}
}
now having two isnt too much of a bad thing, but I am looking at having probably 20+ of these which just becomes awful to use.
Any ideas?
ok further details I think are needed and here they are:
prior to this method I have another method which is recieving a xml doc, which it them deserializes into the interface IService, so we have something like this:
private static void Method(InnerXml)
{
var messageObj = (IServiceTask)XmlSerialization.Deserialize(typeof(IServiceTask), InnerXml);
var service = GetService(messageObj);
service.PerformTask(xmlDoc);
}
private static IService GetService(IServiceTask messageObj)
{
var service = new IService ();
if (messageObj is Task1)
{
service = (SomeService)messageObj;
}
if (messageObj is Task2)
{
service = (SomeOtherService)messageObj;
}
return service ;
}
Hopefully that makes it a bit clearer.
Can you change IService ?
Add method DoSomething() and implement it in all the services.
Well, it depends on what the //DO something lines are doing. In some cases it would be appropriate to declare a method in the service interface and put the logic for those operations in the services themselves.
Sometimes, on the other hand, it's code which the service itself ought not to know about - at which point life becomes distinctly uglier :( Sometimes this sort of thing is really hard to avoid. I've occasionally found that a mixture of generics and lambda expressions help, e.g.
ConditionallyExecute<Service1>(service, s1 => s1.CallSomeService1Method());
ConditionallyExecute<Service2>(service, s2 => s2.CallSomeService2Method());
...
where ConditionallyExecute is something like:
private void ConditionallyExecute<T>(object obj, Action<T> action)
where T : class
{
T t = obj as T;
if (t != null)
{
action(t);
}
}
... but I'm not really happy when I do that :(
I like using a dictionary in these scenarios.
Dictionary<Type,Action<IService>>
What I believe you want is:
class ServiceFactory
{
Dictionary<Type, NewService> serviceCreators;
ServiceFactory()
{
serviceCreators = new Dictionary<Type, NewService>();
serviceCreators.Add(typeof(Task1), delegate { return new SomeService(); });
serviceCreators.Add(typeof(Task2), delegate { return new SomeOtherService(); });
}
public IService CreateService(IServiceTask messageObj)
{
if(serviceCreators.Contains(messageObj.GetType())
{
return serviceCreators[messageObj.GetType()];
}
return new DefaultService();
}
}
delegate IService NewService();
Or maybe to add a new method to IServiceTask - CreateService.
As for me - I would really go with doSomething() method on the Interface so that you could implement it in all these classes. You would have:
public void DoSomething(IService service)
{
service.doSomething();
}
This doesn't make it any better reading, but maybe better performing (if a service can't be two types at the same time):
public void DoSomething(IService service)
{
if (service is Service1)
{
//DO something
}
else if (service is Service2)
{
//DO something else
}
}
Another approach
Maybe this would be also a possible solution:
private Dictionary<Type, Action<object>> _TypeExecutor;
private void SetupExecutors()
{
_TypeExecutor = new Dictionary<Type, Action<object>>();
_TypeExecutor.Add(typeof(Service1), new Action<object>((target) => target.DoSomething()));
_TypeExecutor.Add(typeof(Service2), new Action<object>((target) =>
{
var instance = (Service2)target;
var result = instance.DoSomething();
}));
_TypeExecutor.Add(typeof(Service3), AnotherMethod);
}
private void AnotherMethod(object target)
{
var instance = (Service3)target;
var result = instance.DoSomething();
}
private void DoWork(ISomething something)
{
Action<object> action;
if (_TypeExecutor.TryGetValue(something.GetType(), out action))
{
action(something);
}
}
Generally speaking, if you think you must do something like in your code, this is a strong sign that there is something wrong with your design. If you pass an IService interface to the method, then the intention should ideally be that it wants to call a method on that interface - without caring what implementation is behind!
But apart from that. it might be useful in your case to have some sort of Servicetype property on your IService interface (ideally this would return an enum value), which you could then check with a switch statement. This of course wouldn't reduce the necessary number of logical branches (you won't be able to reduce it without refactoring your architecture), but at least this would significantly reduce the necessary amount of code.
Thomas
If the functionality does not rightly belong in IService then either Wills Command pattern and a Map of some type or by using the visitor pattern.
The latter requires you to add a new method IService.Visit and create interface IServiceVisitor with the methods Visit(Service1) and Visit(Service2) (etc).
Example:
interface IService
{
void Visit(IServiceVisitor visitor);
}
class Service1 : IService
{
void Visit(IServiceVisitor visitor)
{
visitor.Visit(this);
}
}
class Service2 : IService
{
void Visit(IServiceVisitor visitor)
{
visitor.Visit(this);
}
}
interface IServiceVisitor
{
void Visit(Service1 service);
void Visit(Service2 service);
}
class ClassThatDoesStuff : IServiceVisitor
{
{
void Visit(Service1 service)
{
// Service one code
}
void Visit(Service2 service)
{
// Service two code
}
public void DoSomething(IService service)
{
serivce.Visit(this);
}
}
use polymorphism, it's a very simple solution.
class Abstract
{
function something();
}
class A inherit Abstract
{
override something()
}
class B inherit Abstract
{
override something()
}
function foo (Abstract input)
{
input->something()
}
Assuming you want to execute certain method according to the actual type, you can use GetMethod on the instance, and if the method exists invoke it.
public void DoSomething(IService service)
{
System.Reflection.MethodInfo method = service.GetType().GetMethod("MySpecialMethod");
if (method != null)
method.Invoke(service, null);
}
This way you won't have to check the type at all, just check if the method exists - kind of walking around the tree, so I hope this approach is useful.
You can also use array of possible methods and iterating over them, checking each and have more elegant code this way.
Like others have said, the easiest solution would be for this logic to be done inside of your IService implementations themselves through an added method.
If this functionality really does not belong inside of IService though, the Visitor pattern would a much better solution than a large number of instanceof checks.
You would create an interface like
public interface IServiceHandler {
void handleService1(Service1 s);
void handleService2(Service2 s);
// add more methods for every existing subclass of IService
}
With an implementation that handles the logic currently inside of DoSomething, but with every branch separated into it's own method:
public class ServiceHandler : IServiceHandler {
public void handleService1(Service1 s) { ... }
public void handleService2(Service2 s) { ... }
}
IService would then need one addition method:
void accept(IServiceHandler sh);
which would be implemented in the specific implementations like
public class Service1 : IService {
...
public void accept(IServiceHandler sh) { sh.handleService1(this); }
....
}
and analogous for the other implementations.
Your original DoSomething() method can then be rewritten as
public void DoSomething(IService service) {
service.accept(new ServiceHandler());
}
The advantage of this approach is that your logic will be much better segregated, as well as slightly more performant as it no longer uses any instanceof checks or casts.
Also, if you ever add a new implementation of IService, the compiler will force you to add the appropriate handler for it (as it needs to implement the accept() method, which can only be done by adding the appropriate case to IServiceHandler as well), whereas with a solution dependent on a number of type-checks, it would be easy to forget to add the appropriate extra case.
Last but not least, if you ever were to need any other types of handlers, you could do so without needing any further changes to IService; you would simply create a new IServiceHandler implementation with the new logic.
If you write the Service classes yourself, interfaces are the way to go. If Foo() should be called on the object if its either a Service1 or a Service2 then they should implement a common interface and you just check if its either one of the two and then run the relevant code.
If they classes cant be changed, however, then I think youre out of luck. 20+ completely different classes which should have 20+ completely different sets of logic applied to them must simply... be handled differently.
Or am I missing some C# magic here? Every time I see code like this I think of how Go implement interfaces.
Let's say you have two different C# classes A and B that while not deriving from the same base class do share some of the same names for methods. For example, both classes have a connect and a disconnect method, as well as several others. I want to be able to write code once that will work with both types.
Here is a simplified example of what I would like to do:
public void make_connection(Object x)
{
x.connect() ;
// Do some more stuff...
x.disconnect() ;
return ;
}
Of course, this does not compile as the Object class does not have a connect or disconnect method.
Is there a way to do this?
UPDATE. I should have made this clear from the start: I only have the DLLs for A and B and not the source.
You can use an interface to accomplish what you want to do.
interface IConnectable
{
void Connect();
void Disconnect();
}
Both A and B should implement IConnectable. Then use IConnectable instead of Object as the parameter type for your method and you should be all set.
public void MakeConnection(IConnectable connectable)
{
connectable.Connect();
// Do some more stuff...
connectable.Disconnect();
}
Edit: Since you don't have the source code, you have a couple of options:
Use Max's solution of using the dynamic keyword, (if you are using .NET 4.0)
Use Steve's solution of using casting and if/else statements
Create wrapper classes for A and B and have them implement the interface (or use common abstract base class for them)
For example:
class AWrapper : IConnectable
{
private A obj;
public AWrapper(A obj)
{
this.obj = obj;
}
public void Connect()
{
this.obj.Connect();
}
public void Disconnect()
{
this.obj.Disconnect();
}
// other methods as necessary
}
(BWrapper would be similar, just using B instead of A)
Then you could create the wrappers and pass them into MakeConnection. It's up to you how you want to do it. Depending on your situation, one method may be easier than the others.
This will work in C# 4:
public void make_connection(dynamic x)
{
x.connect() ;
// Do some more stuff...
x.disconnect() ;
return ;
}
Try using an Interface rather.
Have a look at interface (C# Reference) and Interfaces (C# Programming Guide)
So something like
public interface IConnections
{
void connect();
void disconnect();
}
public class A : IConnections
{
public void connect()
{
//do something
}
public void disconnect()
{
//do something
}
}
public class B : IConnections
{
public void connect()
{
//do something
}
public void disconnect()
{
//do something
}
}
public void make_connection(IConnections x)
{
x.connect();
// Do some more stuff...
x.disconnect();
return;
}
There is a OOAD concept of 'Programe to an interface not to an implementation' which let's you avoid the chain of inheritance hierarchies
1- You can create a interfcae
interface IConnection
{
void Connect();
void Disconnect();
}
2- And let your classes implement this interface as shown below.
class A : IConnection
{
#region IConnection Members
public void Connect()
{
// your connect method implementation goes here.
}
public void Disconnect()
{
// your disconnect method implementation goes here.
}
#endregion
}
class B : IConnection
{
#region IConnection Members
public void Connect()
{
// your connect method implementation goes here.
}
public void Disconnect()
{
// your disconnect method implementation goes here.
}
#endregion
}
3- Once you done with the implementation than you can make your function accepting an argument of IConnection as shown below.
public void makeConnection(IConnection con)
{
con.Connect();
con.Disconnect();
}
4- And from your client code , you can pass the object of classes which implements IConnect Interface.
If the interface solution is not possible (e.g you don't have source code), another less effecient solution is to use reflection.
As others have said, re-factoring to use interfaces or using the dynamic approach are probably the most elegant ways.
If this is not possible you could cast the object to your types. I'd suggest using as and then checking that the cast worked, an unchecked cast would be dangerous if someone called this with a type that failed to cast.
E.g. If types A and B both have a method called DoSomething() then this will work...
public static void CallDoSomething(object o)
{
A aObject = o as A;
if (aObject != null)
{
aObject.DoSomething();
return;
}
B bObject = o as B;
if (bObject != null)
{
bObject.DoSomething();
return;
}
}
BUT this is pretty ugly to be honest... I'd really try and refactor to interfaces.
Either you will have to use an Interface (or Base class) as shown by Zach and astander, or you will have to case the object before using:
public void make_connection(Object x)
{
((A)x).connect() ;
// Do some more stuff...
x.disconnect() ;
return ;
}
You could also use reflection to invoke the methods
What you want is called Duck Typing.
From Wikipedia:
Duck typing is a style of dynamic typing in which an object's current set of methods and properties determines the valid semantics, rather than its inheritance from a particular class or implementation of a specific interface.
C# 4.0 allows this, as other have said, using the dynamic keyword