public interface IProcessor<T>
{
void Process(T instance);
}
foreach(AbstractType instance in myClass.SomeCollection)
OnProcess(instance);
public void OnProcess<T>(T instance)
{
IProcessor<T> processor =
unityContainer.Resolve<IProcessor<T>>();
processor.Process(instance);
}
The problem with this code is that the in OnProcess is always AbstractType, and not the concrete type of the instance being passed. I currently see two possibilities.
01: Create a non generic IProcessor and use it as the base for IProcessor. Any implementor will have to implement both generic and non-generic Process methods, typically typecasting and passing onto the generic method.
02: Use Type.MakeGenericType to get the IProcessor, resolve that, and then use reflection to invoke the Process method.
Both of these approaches feel a bit "unclean". Can anyone think of a way I can do this without having to resort to these practices?
Thanks
Pete
2 will be a performance killer (the necessary dynamic/relection invoke in particular is slow)
1 is a common answer to this problem, especially with explicit implementation; the problem is getting hold of the type... does unity allow query with a Type instance, rather than via generics? If so something like below... of course, you might still have to use MakeGenericType:
Type intType = typeof(IProcessor<>).MakeGenericType(instanceType);
IProcessor proc = (IProcessor) IoC.Resolve(intType);
Where instanceType is perhaps via instance.GetType(). For similar reasons, it might be helpful to expose the T as a Type on the IProcessor:
public interface IProcessor
{
void Process(object instance);
Type InstanceType {get;}
}
public interface IProcessor<T> : IProcessor
{
void Process(T instance);
}
class SomeClass: IProcessor<int>
{
public void Process(int instance)
{
throw new NotImplementedException();
}
Type IProcessor.InstanceType {get {return typeof(int);}}
void IProcessor.Process(object instance)
{
Process((int)instance);
}
}
Of course, an (optional) base-class might allow you to avoid some of this per-implementation:
abstract class SomeBase<T> : IProcessor<T>
{
public void Process(T instance)
{
OnProcess(instance);
}
Type IProcessor.InstanceType {get {return typeof(T);}}
void IProcessor.Process(object instance)
{
Process((T)instance);
}
protected abstract void OnProcess(T instance);
}
If I understand your problem, you want to call a process that's dependent on 2 types (the type of processor, and the object being processed). Is that right? If that's the case, you can use a multi-method pattern for this kind of problem. Here's an example:
public interface IProcessor
{
void Process( IThingToProcess p ); // Will call p.ProcessMe()
void Process( ThingToProcess1 concreteP ); // Called back from ThingToProcess1.ProcessMe
}
public interface IThingToProcess
{
void ProcessMe( IProcessor p );
}
public class ThingToProcess1 : IThingToProcess
{
public void ProcessMe( IProcessor p ) { p.Process( this ); }
}
Related
My abstract class has a method that is abstract like this:
public abstract void Run(BaseType baseType);
And now in my derived class which has to implement this function, i want it to only accept a specific derived type from BaseType
So it would have:
public override void Run(DerivedType derivedType){}
Is there any way to enforce this at all ?
Currently i have to do:
public override void Run(BaseType baseType) {
if(!(baseType is DerivedType)) {
// throw exception
}
}
It's not very strict with enforcing the type - i was wondering if there is a way to do so without the need to constantly add a type check ?
I've sometimes used this pattern:
public interface IHandler
{
void Run();
}
public abstract class BaseHandler<TObj> : IHandler
where TObj: BaseType
{
protected readonly TObj _obj {get;set;}
public BaseHandler(TObj obj)
{
this._obj = obj;
}
public abstract void Run();
}
public class DerivedHandler : BaseHandler<DerivedType>
{
public DerivedHandler(DerivedType obj) : base(obj)
{
}
public override void Run()
{
// do stuff with base._obj
}
}
public class HandlerService
{
public IHandler CreateHandler<TObj>(TObj obj)
{
// Depending on your DI container, you could resolve this automatically from the container
if (typeof(TObj) == typeof(DerivedType))
{
return new DerivedHandler(obj);
}
throw new NotImplementedException();
}
}
This allows you to define a specific "handler" for each derived type, and then access it through a common interface.
The idea is that you instantiate a specific handler for the object, and then methods like Run() operate on that object. You can then resolve a handler through the service.
I'll fill in some more info later when I have time.
You want the language to do something that it really shouldn't. You want a covariant argument, which violates the Liskov Substitution Principle: It makes the implementation of the abstract class not usable in every situation where the abstract base class is usable. This is the whole point of abstract base classes to begin with.
Although it could make sense to have a covariant return type (returning a more derived type then the abstract methods specifies) the language also prevents you to do that.
I have interface and some classes that implement this interface.
I want to listen for any object that will be instantiated and check if this object implements my interface.
My primary reason is to store all references to this kind of objects and simply call a method of interface to all objects.
As Kyle said in the comments the constructor of an abstract class would be the best choice. Or a factory that must be used for construction of those kind of objects.
But if this is not an option maybe the following approach is acceptable in your case.
If the "listener" is globally accessible (e.g. something static) you can add methods like Register(IYourInterface obj) and Unregister(IYourInterface obj) to it and ensure that every class that implements the interface will call these methods on construction / deconstruction. Not the cleanest way, but it will work as long as you maintain this behavior.
Example:
public static class Listener
{
private static List<IMyInterface> objects = new List<IMyInterface>();
public static void Register(IMyInterface obj)
{
if (!objects.Contains(obj))
objects.Add(obj);
}
public static void Unregister(IMyInterface obj)
{
if (objects.Contains(obj)
objects.Remove(obj);
}
public static void DoSomethingWithObjects()
{
foreach (IMyInterface obj in objects)
// do something ...
}
}
public class SomeTestClass : IMyInterface
{
public SomeTestClass()
{
Listener.Register(this);
}
}
There are a few ways to go about this.
Use a base abstract class
Easiest solution is to have a base class that everything inherits from. This kind of defeats the purpose of the interface, but this is the only way you can add this sort of code for creation. You could do something like:
public abstract class AbstractBaseClass
{
public AbstractBaseClass()
{
ObjectRegister.StoreReference(this);
}
public abstract void MethodToCall();
}
public class SubClass : AbstractBaseClass
{
public SubClass() : base() //Don't forget 'base()'!
{
//Your code here
}
public override void MethodToCall()
{
Console.WriteLine("Called in SubClass");
}
}
The abstract MethodToCall could also be virtual if you want to provide a default action, but if it's abstract the compiler will complain that you haven't implemented it in a similar way to interfaces.
Use a public static instantiating method
A bit more verbose, but can be seen in things like Unity. In this case, instead of doing x = new Y(), you have a public static method, perhaps a generic one, that creates the class for you, registers it, then returns that instance. Assuming your interface is called 'IRegisterable', you could have something like:
public static class ObjectRegister
{
//Note the 'where', which constrains T to be something that
//implements IRegisterable
public static T Instantiate<T>() where T:IRegisterable
{
T obj = new T();
StoreReference(obj);
return obj;
}
private static StoreReference(IRegisterable obj)
{
//Do your storing code here. This doesn't even need to be a method
//if your reference storing stuff only happens on object creation
}
}
//Elsewhere, where class 'Thing' implements IRegisterable
Thing x = ObjectRegister.Instantiate<Thing>();
//x is now registered. No need to do x = new Thing()
string y = ObjectRegister.Instantiate<string>();
//Error: string does not implement IRegisterable
Unfortunately, supplying constructor arguments this way isn't easy. You could just have an Init() method though which acts as a sort of fake constructor.
Consider the following piece of code:
class MyClass
{
}
class MyClass2 : MyClass
{
}
private void Foo(MyClass cl)
{
//cl is actually MyClass2 instance
TestGeneric(cl);
}
private void TestGeneric<T>(T val)
{
//do smth
}
After calling Foo(), the T in TestGeneric is MyClass, not MyClass2.
How do I achieve treating val as a MyClass2 instance?
Thanks in advance.
Upd:
I don't actually know that the object has been created using MyClass2 ctor, but rather can infer this by calling val.GetType() so a simple as MyClass2 won't work
It can be done with a visitor pattern. It is a nice object oriented approach, when you have all handling code in a single handler class (not in each message) and if more message types will be needed, just add additional handler methods.
// Your message classes
public class MyClass : IMessage
{
// Implement acceptance of handler:
public void AcceptHandler(IMessageHandler handler)
{
handler.HandleMessage(this);
}
}
public class MyClass2 : MyClass
{
// Nothing more here
}
// Define interface of message
public interface IMessage
{
void AcceptHandler(IMessageHandler handler)
}
// Define interface of handler
public interface IMessageHandler
{
// For each type of message, define separate method
void HandleMessage(MyClass message)
void HandleMessage(MyClass2 message)
}
// Implemente actual handler implementation
public class MessageHandler : IMessageHandler
{
// Main handler method
public void HandleSomeMessage(MyClass message) // Or it could be IMessage
{
// Pass this handler to message. Since message implements AcceptHandler
// as just passing itself to handler, correct method of handler for MyClass
// or MyClass2 will be called at runtime.
message.AcceptHandler(this);
}
public void HandleMessage(MyClass message)
{
// Implement what do you need to be done for MyClass
}
public void HandleMessage(MyClass2 message)
{
// Implement what do you need to be done for MyClass2
// If code of MyClass should be run too, just call
// this.HandleMessage((MyClass)message);
}
}
Assuming you can change Foo, but not its signature, you could do this:
private void Foo(MyClass cl)
{
TestGeneric((dynamic)cl);
}
This will resolve the version of TestGeneric that gets called at runtime instead of at compile time, calling TestGeneric<MyClass2> when cl is of that type.
Well when you call a generic method, the type parameters will be resolved based on the types of the variables, and not based on the types of the actual values.
So for example if you have:
var x = int as object;
Foo(x);
and then you have this:
void Foo<T>(T value)
{
}
Then the type of T will be object and not int, because that's the type of the variable.
A possible solution would be to dynamically cast the value to the lowest subclass, using either reflection or a compiled expression.
Some other alternatives you have are to use reflection to check the actual type of the value that was passed and base your logic on that, or use other language mechanics such as virtual methods.
If you describe the scenario you are trying to solve, someone could probably suggest a suitable solution.
(Answering the question from the comment)
It's a bulky solution, and you are depending on concrete implementations, but you could do something along these lines:
//initialization
Dictionary<Type, Action> typeActions = new Dictionary<Type, Action>();
typeActions.Add(typeof (MyClass), () => {Console.WriteLine("MyClass");});
typeActions.Add(typeof (MyClass2), () => {Console.WriteLine("MyClass2");});
private void TestGeneric<T>(T val)
{
//here some error checking should be in place,
//to make sure that T is a valid entry class
Action action = typeActions[val.GetType()];
action();
}
A downside to this approach is that it depends on the variables being exactly of type MyClass or MyClass2, so if someone later adds another level of inheritance, this will break, but still, it's more flexible than a if-else or a switch in the generic method.
A cast is when you know more about the type of an object than the compiler is able to deduce from the static code.
This leaves you with two options when ever you need more type information that you currently have.
Change the declaration to make the information explicit at declaration
Make a cast
or go dynamic
In your case the first would require changing Foo to be generic too
private void Foo<T>(T cl)
{
//cl is actually MyClass2 instance
TestGeneric(cl);
}
The second option would require casting and I'm guessing you have multiple types so you'll need a lot of if-else-if's which is generally a bad sign especially when the condition is based on the type of an object
private void Foo(MyClass cl)
{
var mc2 = tcl as MyClass2;
if(mc2 != null) {
TestGeneric(mc2);
return;
}
var mc3 = tcl as MyClass3;
if(mc3 != null) {
TestGeneric(mc3);
return;
}
throw new InvalidOperationException("Type not recognised");
}
lastly you could go dynamic
private void TestDynamic(dynamic val)
{
TestGeneric(val);
}
There are other ways of doing it dynamically such as runtime generating code but it's a lot easier to simply use the DLR than trying to role your own on
You don't want to call a generic method here. Once you enter TestGeneric<T>, even if T is MyClass2 as you want, you can't have written any code against MyClass2 (or even MyClass, unless you add a restriction on T) so it doesn't help!
You certainly don't need to go down the route of reflection or dynamic.
Most obvious way to do this: put the class-specific behaviour in the class itself:
class MyClass
{
public virtual void Test()
{
// Behaviour for MyClass
}
}
class MyClass2 : MyClass
{
public override void Test()
{
// Behaviour for MyClass2
}
}
private void Foo(MyClass cl)
{
cl.Test();
}
Next-best: branch code depending on the type passed:
private void Foo(MyClass cl)
{
if (cl is MyClass2)
{
Test((MyClass2)cl);
}
else
{
Test(cl);
}
}
private void Test(MyClass cl)
{
// Behaviour for MyClass
}
private void Test(MyClass2 cl2)
{
// Behaviour for MyClass2
}
In both these cases you can write code directly against MyClass2 (or MyClass) without having to do any reflection, use dynamic, or... whatever you were planning to do in your generic method - branch on typeof(T)?
Best solution would be to change Foo method to be generic too, so that you can save type information. You should do this like so:
private void Foo<T>(T cl) where T : MyClass
{
TestGeneric(cl);
}
Otherwise, you would have an example of bad design. Simple way out would be
private void Foo(MyClass cl)
{
if (cl is MyClass2)
TestGeneric((MyClass2)cl);
else
TestGeneric(cl);
}
You could also do a broader solution using reflection, but that would be abuse of tools to patch bad design.
Following would be a reflection based solution, but I did not run it so bear with me and try to fix possible errors.
private void Foo(MyClass cl)
{
Type genMethodType = typeof(TestGenericMethodClass);
MethodInfo genMethod = genMethodType.GetMethod("TestGeneric");
MethodInfo methodConstructed = genMethod.MakeGenericMethod(cl.GetType());
object[] args = new object[] { cl };
methodConstructed.Invoke(instanceOfTestGenericMethodClass, args);
}
So
Get type of class in which your TestGeneric method is defined
Use Type.GetMethod to retrieve method definition
Retrieve actual type of your cl variable to construct generic method
Use MethodInfo.MakeGenericMethod to construct a method for specific type
Use MethodBase.Invoke to invoke constructed method
Your code will differ based on your current implementation (depending on type names, method accessibility and such).
Given the scenario...
interface IBase{
void Process(int value);
}
abstract class Base : IBase
{
public virtual void Process(int value){ throw new NotImplementedException(); }
}
class Implemented: Base, IBase
{
public void Process(int value)
{
// .. some code here..
}
}
I'm trying to write a loop similar to the following.
foreach( Base b in CollectionOfImplemented )
{
b.Process( // something will go here // );
}
Trying this, it keeps calling Base.Process, instead of Implemented.Process; but the type in the collection is Implemented, not Base. Boxing it seems to work, but I was hoping to see if I could find a more intelligent approach to it, since the Collection will contain other types of objects that also inherit from Base.
You need to explicitly override Process in Implemented:
class Implemented: Base
{
public override void Process(int value)
{
// .. some code here..
}
}
Or you won't get virtual method dispatching.
Also, if your base method is always going to throw that NotImplementedException, it should be marked as abstract instead.
I think you need to specify "override" for Process in your Implemented class.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why cannot C# generics derive from one of the generic type parameters like they can in C++ templates?
I can do
public class MyGenericClass : DL
//but i cannot do
public class MyGenericClass <T> : T
How would i do the second? if i cannot do that, how can i do something like
public class MyGenericClass <T>
{
T obj;
//have all MyGenericClass.XYZ call obj.XYZ
}
This is not possible, because depending on what type T is, the public interface of MyGenericClass would change.
If you have lots of different classes that all expose the same interface, you could declare MyGenericClass to expose that interface, and in the implementation of all of the functions delegate the calls to obj
The specific question, why can't you do this:
public class MyGenericClass<T> : T
And you can do this:
public class MyGenericClass<T>
{
T obj;
}
The reason is that the CLR likes to be able to compile a single version of the code for MyGenericClass that will work for any reference type specified for T.
It can do this for the second case, because it can quietly replace T with object and insert appropriate casts, roughly equivalent to:
public class MyGenericClass
{
object obj;
}
But for the inheritance version, that trick doesn't work.
Also, many useful facilities would be impossible to describe through interface constraints. When you inherit from a type, you can do a lot more than just call methods on it - you can override them as well. Consider this hypothetical example:
class MyBase
{
public virtual void MyVirtual() { }
}
class MyGenericDerived<T> : T
{
public override void MyVirtual()
{
Console.WriteLine("Overridden!");
}
}
MyBase obj = new MyGenericDerived<MyBase>();
obj.MyVirtual();
What I want to do there is something like a "mix-in", where MyGenericDerived supplies definitions for virtual functions in whatever base it is applied to. But how does the compiler know that T will have a method called MyVirtual that can be overridden? I'd need to put a constraint on T. How would I express that through interfaces? It's impossible. Using interfaces to describe constraints isn't an adequate solution once you allow inheritance from type parameters. So that's another reason why it doesn't exist in the language today.
You could do something like
public interface IXyzable { void xyz(); }
public class MyGenericClass<T> : IXyzable where T : IXyzable {
T obj;
public void xyz() {
obj.xyz();
}
}
Edit: Now I understand the question
You'll need all your possible T's to implement some interface so that you know that obj.XYZ() makes sense, then you can do
public interface Ixyz
{
void XYZ();
}
public class MyGenericClass<T> : Ixyz where T:Ixyz, new()
{
T obj;
public MyGenericClass()
{
obj = new T();
}
public void XYZ()
{
obj.XYZ();
}
}
I've made MyGenericClass implement Ixyz too since it obviously does expose the right method, but maybe that's best left out since it allows
var x = new MyGenericClass<MyGenericClass<SomeClass>>();
which is unlikely to ever be a good idea.
This is pretty much duck-typing, but you could use reflection.
When you create the generic class with a reference to the obj, use reflection to try and find a method with the right signature. As long as you store a reference to the method, performance won't be too bad.
class BaseGeneric<T>
{
private T obj;
private MethodInfo mi;
private const string MethodNameOfInterest = "Xyz";
public BaseGeneric(T theObject)
{
this.obj = theObject;
Type t = obj.GetType();
mi = t.GetMethod(MethodNameOfInterest);
}
public void Xyz()
{
mi.Invoke(obj, null);
}
}
Of course, you would need to add a lot more for error checking and such, but that is the gist of what you could do. Also, don't forget to add the System.Reflection namespace to your using clause.
The .NET type system won't allow type declarations of the form you're attempting. One reason why this is disallowed should be intuitive: how would MyGenericClass<T> act when T is a sealed class (e.g. System.String)?
If you absolutely need this functionality (and you know that the type T you'll be using isn't sealed), you can generate proxies at runtime using the classes in the Reflection.Emit namespace. It may also be possible to achieve this effect using AOP tools like PostSharp.
What about this:
class BaseClass<T>
{
public T property { get; set; }
}
class GenericClass<T> : BaseClass<T>
{
}
class Program
{
static void Main(string[] args)
{
GenericClass<int> l = new GenericClass<int>();
l.property = 10;
}
}
This achieves what you want to do?