C# code to handle different classes with same method names - c#

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

Related

Guideline for writing callbacks via various tricks

I am confused in deciding whether I should use
a polymorphic (via overriding the virtual method A) method.
a delegate-type-parameterized method B.
an event C.
an instance of a class implementing an interface with a single method D. A Java's trick!
when writing callbacks.
using System;
namespace CallBack
{
interface IOptional
{
void D();
}
class Base
{
protected virtual void A() => Console.WriteLine("Base's extra jobs.");
public void Do(Action B = null, IOptional optional = null)
{
Console.WriteLine("Base's main jobs.");
// and call the optional jobs
A();
B?.Invoke();
C?.Invoke();
optional?.D();
}
public event Action C;
}
class Derived : Base
{
protected override void A()
{
base.A();
Console.WriteLine("Derived's extra jobs.");
}
}
class Optional : IOptional
{
public void D()
{
Console.WriteLine("D");
}
}
class Test
{
static void Main()
{
Derived d = new Derived();
d.C += () => Console.WriteLine("C");
d.Do(() => Console.WriteLine("B"), new Optional());
}
}
}
Question
Is there any commonly used guideline for agile programmers?
The use cases of the three seem quite distinct to me :)
The core idea is "who do you want to let know about the event".
If you want to allow everyone to be able to subscribe to it, use an event. This is also what most of .NET that I have experience with deal with callbacks.
By using the polymorphism approach, you only allow subclasses to know about the event. If some other object wants to do something when it happens, it can't, because it's not a subclass and can't override the method.
By using the delegate parameter approach, you limit the number of subscribers to 1. Any caller can subscribe to the event, but subscriber-event is now a one-to-one relationship.

Mutually exclusive abstract methods in C#

I am developing a C# library where the user needs to write his/her own classes inheriting from given classes from the library. I don't think writing further details will be helpful, so please even if what I am asking for looks strange, consider it as such.
In one class, I would like the following behavior: two mutually exclusive "abstract" methods such that if one is implemented then there is no need to implement the other (so right, they are not really abstract).
I need to force the user to implement at least one of these methods, so declaring both methods virtual only is not enough. Actually I could declare both abstract, but it means the user should implement a method that would never be called afterwards and of course I want to avoid that.
Is there a trick or a C# idiom to do something close to what I want? Maybe with some reflection tricks I know almost nothing about?
I think what you're trying to do is violating a lot of Object-Oriented design goals.
"I need to force the user to implement at least one of these methods"
If the two classes need to have functionality that is is one thing or the other, why not just have 1 abstract method (or create an interface), and have the two classes override that method differently? Then you force each class to implement one part of the functionality and the other implement the other type.
I would recommend re-thinking your approach rather than spending tons of time trying to make a poor approach work.
EDIT:
Based on your comments I'll try to go into a bit more detail.
You could try something like the following. But I suspect you'll need to expand it significantly to get it working. But this should get you started anyway
public class ResultFromMethod1 {
public bool optimized = false;
// other results here
}
This stores the results from method 1 and tells you how method 1 was run.
public interface IInterfaceForMethod1 {
ResultFromMethod1 Method1 ();
}
public interface IInterfaceForMethod2 {
void Method2 (ResultFromMethod1 resultFromMethod1, Vector v);
}
These are the interfaces for the two methods. Note that they are not implemented yet. This is just a contract for classes that implement them.
public class UnoptomizedImplementation : IInterfaceForMethod1, IInterfaceForMethod2 {
#region IInterfaceForMethod1 implementation
public ResultFromMethod1 Method1 () {
ResultFromMethod1 resultFromMethod1 = new ResultFromMethod1 ();
resultFromMethod1.optimized = false;
// Method1 logic here
return resultFromMethod1;
}
#endregion
#region IInterfaceForMethod2 implementation
public void Method2 (ResultFromMethod1 resultFromMethod1, Vector v) {
if (!ResultFromMethod1.optimized) {
//if NOT optimized
//logic here
}
else {
//throw exception
}
}
#endregion
}
These class runs method1 not optimized, and then has a method2 that requires method 1 be not optimized. If you don't need method2 when it's not optimized then just don't implement the method2 interface.
public class OptimizedImplementation : IInterfaceForMethod1, IInterfaceForMethod2 {
#region IInterfaceForMethod1 implementation
public ResultFromMethod1 Method1 () {
ResultFromMethod1 resultFromMethod1 = new ResultFromMethod1 ();
resultFromMethod1.optimized = true;
// Method2 logic here
return resultFromMethod1;
}
#endregion
#region IInterfaceForMethod2 implementation
public void Method2 (ResultFromMethod1 resultFromMethod1, Vector v) {
if (ResultFromMethod1.optimized) {
//if optimized
//logic here
}
else {
//throw exception
}
}
#endregion
}
This class requires an output from method1 that is optimized or it throws an exception.
I hope that sends you down a more manageable track.
I suggest implementing interfaces
public interface IMyMethod1 {
void MyMethod1();
}
public interface IMyMethod2 {
void MyMethod2();
}
and inject a dependency
public class MyClass {
...
public MyClass(IMyMethod1 method1, IMyMethod2 method2) {
if ((null == method1) && (null == method2))
throw new ArgumentNullException("method1",
"You should provide either method1 or method2");
m_Method1 = method1;
m_Method2 = method2;
}
...
public void DoSomething() {
...
if (m_Method1 != null)
m_Method1.MyMethod1();
else if (m_Method2 != null)
m_Method2.MyMethod2();
...
}
}
To avoid reflection, create you base class (abstract) without either of those two methods.
Then, create separate classes (abstract) inheriting your base class for both of the "special" methods.
This will require some type-checking and casting, but it's all I got right now.

Confusion in implementing adapter pattern

I am learning Adapter pattern, and used following link to see code. Difference in my code and example code is, I removed ITarget interface, and directly created object in Client.
I know importance of using Interface, but is it really necessary to use interface, more specifically, by not creating interface, am I violating Adapter Pattern rule?
Adapter Pattern Example
My Code (without interface)
class Program
{
static void Main(string[] args)
{
Adapter obj = new Adapter();
Client client = new Client(obj);
client.MakeRequest();
}
}
public class Client
{
private Adapter _target;
public Client(Adapter target)
{
_target = target;
}
public void MakeRequest()
{
_target.MethodA();
}
}
public class Adaptee
{
public void MethodB()
{
Console.WriteLine("MethodB called");
}
}
public class Adapter
{
Adaptee _adaptee = new Adaptee();
public void MethodA()
{
_adaptee.MethodB();
}
}
Thanks.
The whole point of an adapter is that the adaptee can be used wherever a certain type is needed which is not the adaptee's type.
Assume that you have a method MyMethod(MyParameterType m). This method expects a parameter of type MyParameterType. But you don't have an object of this type. Instead you have an object that has similar functionality (maybe from a third-party library). However, this object is not of type MyParameterType, but of type MyOtherType. Of course, you can't directly pass the object to the method. That's where the adapter comes into play.
You need an object to pass to the method. Hence, it is essential that this object is of type MyParameterType; may it be an interface or class. So the Adapter has to implement or inherit this type. Otherwise, it does not make sense. You would just have another class with the same functionality as the object of type MyOtherType, but you can't use it anywhere.
Summarizing, the adapter is used to bridge architectural mismatch. This often occurs when you have several libraries that need to play together but were not supposed to do so. If you have only code that has been developed by yourself, adapters are rarely necessary because you can let the objects just implement the interface you need. This is not possible in third-party code. So you introduce adapters for that. So in the end, the adapter disguises an object to look familiar to a client, even if it is not. The interface is necessary to make it familiar. So yes, your code is not an adapter.
The problem here is you've explicitly coupled Client to the Adapter and implicitly to the behavior of how that adapter works.
Interfaces and this pattern pay off when you start using dependency injection.
Assume I have:
public Client(IAdapter target) ...
Now I can change the behavior of the adapter implementation without the Client class being changed at all:
interface IAdapter
{
void MethodA();
}
interface IAdaptee
{
void MethodB();
}
class Adapter<TAdaptee> : IAdapter where TAdaptee : IAdaptee, new()
{
private TAdaptee _adaptee;
public Adapter()
{
_adaptee = new TAdaptee();
}
public void MethodA()
{
_adaptee.MethodB();
}
}
class AdapteeA : IAdaptee
{
public void MethodB()
{
Console.WriteLine("AdapteeA");
}
}
class AdapteeB : IAdaptee
{
public void MethodB()
{
Console.WriteLine("AdapteeB");
}
}
Then with something like NInject you bind up your system:
class Program
{
private static StandardKernel _kernel;
static void Main(string[] args)
{
_kernel = new StandardKernel();
_kernel.Bind<IAdapter>().To<Adapter<AdapteeA>>();
var adapter = _kernel.Get<IAdapter>();
adapter.MethodA();
}
}
You can change your adapter and your adaptee, without client ever knowing the difference. i.e. Client is decoupled from both.
Again to make this point I can change to AdapteeB:
_kernel.Bind<IAdapter>().To<Adapter<AdapteeB>>();
It does go further too, with things like contra-variance, but that is beyond scope.

TOO MANY if (obj is thisObj) statements

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.

How to cast an interface to its sub interface?

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();
}

Categories