I have two classes Say A and B which has method set().
public Class A : I<string>
{
void Set(string str)
{
//do something
}
}
public Class B : I<int>
{
void Set(int str)
{
//do something
}
}
And an interface as follows...
interface I<T>
{
void Set(T param);
}
I would like to access this method without instantiating the classes, through interface (Is it possible or is there any other way like dependency injection?).
From another Class
Class D
{
I.Set(<T> str); //something like this
}
So based on data type I need to redirect the call from either interface or some where, so that if tomorrow I added a class say C which implements same interface, I should not end up with changing code in D.
Thanks in Advance...
An interface is sort of like a template of methods an implementing class provides. You can not "do anything" with an interface. You always need an instance of a class implementing the interface.
So what you want does not work. However, a simple extension method will help you here:
public static class MyExtensionMethods
{
public static void SetValue<T>(this I<T> intf, T value)
{
intf.Set(value);
}
}
Using this, you can write:
A a = new A();
B b = new B();
b.SetValue("Hello");
a.SetValue(1);
And it will work for any other classes that implement I<T> without having to change the extension method:
public class D : I<double>
{
public void Set(double d) { ... }
}
D d = new D();
d.SetValue(42.0);
You need to pass in something, so at the moment, my best guess would be
class D
{
public void Set<T>(object target, T value)
{
var instance = target as I<T>;
if (instance != null)
{
instance.Set(value);
}
}
}
Called like:
var theD = new D();
var theA = new A();
var theB = new B();
theD.Set<string>(theA, "hello");
theD.Set<int>(theB, 1);
Related
Let's suppose there is a following class:
public class foo{
internal virtual object M1(/*args*/){return null;}
internal virtual object[] M2(/*args*/){return null;}
public SomeStruct SomeMethod(){
return new SomeStruct
{
Obj = M1();
ObjArr = M2();
}
}
}
Using the following struct:
public class SomeStruct
{
public object Obj;
public object[] ObjArr;
}
Is there a way to make sure (preferably at compilation) to force either at least one method or exactly one method of class foo to be overriden?
Before anybody says it - I know it's possible to use one method and check if the result is array (or IEnumerable) and then assign it to the right field, but that takes more time then just running empty methods. I'm just wondering if it's possible to do it that way.
You could mark the methods abstract, and then you will be forced to implement both of the methods. This seems to be the most straightforward solution:
internal abstract object M1(/*args*/){return null;}
internal abstract object[] M2(/*args*/){return null;}
Another option, actually too complicated for this purpose, is to write a Roslyn code analyzer which will check the code and determines if it is valid.
As a side note: your fields should reside in the base class too. You could use generics if you want to make the types of them generic.
"No", basically. At least, not without writing your own custom code analyzer (perhaps via Roslyn), and considering what happens if X : foo overrides M1, and Y : X overrides M2.
You need to create a new method in your child class that hides the implementation of the base class, with the new return type. You cannot use virtual methods to overload a method like you're doing.Overloading of methods is done by changing the parameters, not the return type.
So either hide the parent method, in the child class, or create a method with another name.
Here is something that I can think of, just an example.
Run it here .Net Fiddle
using System;
public class a
{
public virtual object s(int a)
{
return a + 1;
}
}
public class b : a
{
public virtual object[] s(int a)
{
var arr = new object[]{a + 2};
return arr;
}
}
public class c : b
{
private a A = new a();
private b B = new b();
public c()
{
print(2);
}
public void print(int a)
{
var result = A.s(1);
Console.WriteLine("result : " + result);
var resultB = B.s(1);
//or resultB = base.s(1);
foreach (var r in resultB)
{
Console.WriteLine("result B : " + r);
}
}
}
public class Program
{
public static void Main()
{
c C = new c();
}
}
So say I have three classes: A, B, and C. A is abstract, B and C inherit from A.
I have created a list of A classes. In a function, I need to know the type of the class I have: A, B, or C. Do I use reflection to get the name? Assign it a type variable and check that? Or am I using abstraction fundamentally wrong?
public abstract class A
{
public string Type
{
get;
set;
}
}
public class B : A
{
public B()
{
this.Type = "B";
Console.WriteLine("I am of type B!");
}
}
public class C : A
{
public C()
{
this.Type = "C";
Console.WriteLine("I am of type C!");
}
}
List<A> listOfStuff = new List<A>();
void doSomething()
{
listOfStuff.Add(new A());
listOfStuff.Add(new B());
listOfStuff.Add(new C());
foreach (A item in listOfStuff)
{
doOperation(item);
}
}
void doOperation(A thing1)
{
//Is this bad practice?
if (thing1.GetType().Name == "B")
{
//Do code
}
//Or what about this?
if (thing1.Type == "B")
{
//Do code
}
}
This is perhaps a violation of the Liskov substitution principle, the L in SOLID. If a bunch of "A"s are in a list, it should be possible to operate on them without "knowing" their subtype. If they're all going to be cast as A but then you have to reinspect them to determine their actual type and handle them differently then it defeats the purpose of being able to refer to them by their base type.
If the different types can all expose the same properties (describing area, dimensions, etc.) then an interface might be better than an abstract class.
No need to work that hard. Just use is
public abstract class A
{
}
public class B : A
{
public B()
{
Console.WriteLine("I am of type B!");
}
}
public class C : A
{
public C()
{
Console.WriteLine("I am of type C!");
}
}
static List<A> listOfStuff = new List<A>();
public static void doSomething()
{
listOfStuff.Add(new B());
listOfStuff.Add(new C());
foreach (A item in listOfStuff)
{
doOperation(item);
}
}
static void doOperation(A thing1)
{
if (thing1 is B)
{
//Do code for B
}
if (thing1 is C)
{
//Do code for C
}
}
Rob Deary has already shown you how to avoid doing it but he didn't specifically answer your question.
I would say that "code smell" is far too mild a term for what you wrote in your OP. The only good case I can see for using reflection to find an object's type is some sort of logging or reporting function. (Something that's going to print "I got a B".) It would be possibly tolerable if it was needed to work around a bug in code you couldn't fix. Beyond that don't do it.
I know it sounds trivial, but is it somehow possible to return the b field when i pass an A variable to a function which expects an IMyIntercace? Then i don't have to implement the Hello() function in the class A, instead i just return b as the IMyInterface.
interface IMyInterface
{
void Hello();
}
class A : IMyInterface
{
B b = new B();
}
class B : IMyInterface
{
public void Hello()
{
Console.WriteLine("Hello");
}
}
class Program
{
static void foo(IMyInterface myInterface)
{
myInterface.Hello();
}
static void Main(string[] args)
{
A someVariable = new A();
foo(someVariable);
}
}
I suppose it cant be done, but is there any design pattern or trick that could do it?
EDIT
The reason i dont want to derive A is because maybe i want to do this
class A : IMyInterface
{
B b = new B();
B b2 = new B();
IMyInterface bPointer;
}
Then i can point to one of the b's depending on some situation
You could inherit A from B.
A will continue to implement the interface and you may override every function you need to change in the future.
interface IMyInterface
{
void Hello();
}
class A : B
{
}
class B : IMyInterface
{
public void Hello()
{
Console.WriteLine("Hello");
}
}
No. Either A implements IMyInterface, in which case you don't need to do anything, or it does not, in which case there is no way to automatically "redirect" any interested parties to the b member.
You can either expose b (and preferably make it a property) to the outside world so that they can refer to it as required, or you can make A implement IMyInterface and manually forward all calls to b like this:
class A : IMyInterface
{
B b = new B();
public void Hello()
{
b.Hello();
}
}
Just make A.b public (or internal) and then call foo(someVariable.b).
What you want to have is interface delegation and unfortunately there is nothing built into the language to help you with that.
Basically, the A class has to implement the interface.
One way it can do that is of course to derive from B:
class A : B
{
}
But if you don't want to do that, then you need to delegate. What you have to do is to implement the delegation yourself so that you can delegate the responsibility of the actual implementation to the B class, you won't get any help from the compiler to fix this.
class A : IMyInterface
{
B b = new B();
public void Hello()
{
b.Hello();
}
}
Let's say I have a generic class as follows:
public class GeneralPropertyMap<T>
{
}
In some other class I have a method that takes in an array of GeneralPropertyMap<T>. In Java, in order to take in an array that contains any type of GeneralPropertyMap the method would look like this:
private void TakeGeneralPropertyMap(GeneralPropertyMap<?>[] maps)
{
}
We use the wildcard so that later we can call TakeGeneralPropertyMap passing a bunch of GeneralPropertyMap with any type for T each, like this:
GeneralPropertyMap<?>[] maps = new GeneralPropertyMap<?>[3];
maps[0] = new GeneralPropertyMap<String>();
maps[1] = new GeneralPropertyMap<Integer>();
maps[2] = new GeneralPropertyMap<Double>();
//And finally pass the array in.
TakeGeneralPropertyMap(maps);
I'm trying to figure out an equivalent in C# with no success. Any ideas?
Generics in C# make stronger guarantees than generics in Java. Therefore, to do what you want in C#, you have to let the GeneralPropertyMap<T> class inherit from a non-generic version of that class (or interface).
public class GeneralPropertyMap<T> : GeneralPropertyMap
{
}
public class GeneralPropertyMap
{
// Only you can implement it:
internal GeneralPropertyMap() { }
}
Now you can do:
private void TakeGeneralPropertyMap(GeneralPropertyMap[] maps)
{
}
And:
GeneralPropertyMap[] maps = new GeneralPropertyMap[3];
maps[0] = new GeneralPropertyMap<String>();
maps[1] = new GeneralPropertyMap<Integer>();
maps[2] = new GeneralPropertyMap<Double>();
TakeGeneralPropertyMap(maps);
While, as others have noted, there's no exact correspondence to wildcards in c#, some of their use cases can be covered with covariance/contravariance.
public interface IGeneralPropertyMap<out T> {} // a class can't be covariant, so
// we need to introduce an interface...
public class GeneralPropertyMap<T> : IGeneralPropertyMap<T> {} // .. and have our class
// inherit from it
//now our method becomes something like
private void TakeGeneralPropertyMap<T>(IList<IGeneralPropertyMap<T>> maps){}
// and you can do
var maps = new List<IGeneralPropertyMap<Object>> {
new GeneralPropertyMap<String>(),
new GeneralPropertyMap<Regex>()
};
//And finally pass the array in.
TakeGeneralPropertyMap<Object>(maps);
The caveat is that you can't use covariance with value types, so adding a new GeneralPropertyMap<int>() to our list fails at compile time.
cannot convert from 'GeneralPropertyMap<int>' to 'IGeneralPropertyMap<object>'
This approach may be more convenient than having a non-generic version of your classes/interfaces in case you want to constrain the types that GeneralPropertyMap can contain. In that case:
public interface IMyType {}
public class A : IMyType {}
public class B : IMyType {}
public class C : IMyType {}
public interface IGeneralPropertyMap<out T> where T : IMyType {}
allows you to have:
var maps = new List<IGeneralPropertyMap<IMyType>> {
new GeneralPropertyMap<A>(),
new GeneralPropertyMap<B>() ,
new GeneralPropertyMap<C>()
};
TakeGeneralPropertyMap(maps);
There is no direct equivalent to this in C#.
In C#, this would often be done by having your generic class implement a non-generic interface or base class:
interface IPropertyMap
{
// Shared properties
}
public class GeneralPropertyMap<T> : IPropertyMap
{
}
You could then pass an array of these:
IPropertyMap[] maps = new IPropertyMap[3];
// ...
TakePropertyMap(maps);
Make an interface from the members of GeneralPropertyMap (IGeneralPropertyMap), and then take an IGeneralPropertyMap[] as an argument.
Actually, you can get pretty close to a wildcard by using dynamic. This also works nicely if you have a non-generic superclass.
For example:
public class A
{
// ...
}
public class B<T> : A
{
// ...
}
public class Program
{
public static A MakeA() { return new A(); }
public static A MakeB() { return new B<string>(); }
public static void Visit<T>(B<T> b)
{
Console.WriteLine("This is B with type "+typeof(T).FullName);
}
public static void Visit(A a)
{
Console.WriteLine("This is A");
}
public static void Main()
{
A instA = MakeA();
A instB = MakeB();
// This calls the appropriate methods.
Visit((dynamic)instA);
Visit((dynamic)instB);
// This calls Visit(A a) twice.
Visit(instA);
Visit(instB);
}
}
How this works is explained in the C# documentation here.
class A implements IC
class B implements IC
class Factory has a method GetObject(int x); x=0 for A, x=1 for B.
How can I force the usage of Factory.GetObject method to create objects of type A and B and prevent something like new A(), which should be Factory.GetObject(0)?
How can I force the usage of Factory GetObject method to create objects of type A and B and prevent something like new A()
You can't force the usage of Factory.GetObject, this is something that you should write in the documentation of the API you are providing after marking A and B constructors internal.
public class A: IC
{
internal A() { }
}
public class B: IC
{
internal B() { }
}
public static class Factory
{
public static IC GetObject(int x)
{
if (x == 0)
{
return new A();
}
if (x == 1)
{
return new B();
}
throw new ArgumentException("x must be 1 or 2", "x");
}
}
This way those constructors will not be accessible from other assemblies. Also don't forget about Reflection which will allow for direct instantiation of those classes no matter how hard you try to hide them.
I'm not sure if it's still relevant (it's been a year...) but here's how you can achieve further enforcement of the factory usage:
public class A
{
internal protected A() {}
}
public class AFactory
{
public A CreateA()
{
return new InternalA();
}
private class InternalA : A
{
public InternalA(): base() {}
}
}
Components using class A cannot directly create it (so long they don't inherit it...).