c# generics

Started by
3 comments, last by Nypyren 14 years, 3 months ago
hello, I am trying to do some input handling by regestering "InputHandlers" with my input handleing class. For simplicity Sake sake I have "Player" object, it would then have an object "PlayerInputHandler" that it owns and that contains a reference to the Player. It registers this with the input handler, when the input handler has a key pressed it calls "KeyDown" on the PlayerInputHandler. The handler can do whatever I want BUT what I notice is that all I do is call OnKeyDown on my player and forward it on. I do this on several classes so the input handler just becomes an input forwarder. I realise I could make my objects a type of input handler but I dont' want to. So what I am trying to do is make a generic "InputForwarder" class like so:

    class InputForwarder<T> :  InputHandler
    {
        T forwardObject;

        public InputForwarder(T target)
        {
            forwardObject = target;
        }

        public override void OnKeyDown(Keys key)
        {
            forwardObject.KeyDown(key);
        }

        public override void OnKeyUp(Keys key)
        {
            forwardObject.KeyUp(key);
        }
    }
However it won't compile and I can't figure out why. Errors are on the following: forwardObject.KeyDown(key); forwardObject.KeyUp(key); The error is: error CS1061: 'T' does not contain a definition for 'KeyUp' and no extension method 'KeyUp' accepting a first argument of type 'T' could be found checking that error it just means my class doens't have the method but I thought this would only be an issue when I actually try to make an object of this type (not got that far). I've read a bit about generics trying to solve this problem but I don't see any examples doing this. Any help is most appreciated. Thanks.

Interested in Fractals? Check out my App, Fractal Scout, free on the Google Play store.

Advertisement
There are a couple ways I usually solve that kind of design:

1. Put a constraint on the generic type:
class InputForwarder<T> : InputHandler where T: IForwardObject


or since you probably would constrain on an interface anyway, just simplify it as...

2. Replace the <T> with an interface:
public interface IForwardObject{  void KeyDown(Keys key);  void KeyUp(Keys key);}class InputForwarder : InputHandler{  IForwardObject forwardObject;}



Personally I always go with #2.
I saw those constrains things, didn't really understand them. I like the sound of 2) but I don't have to make my Player etc objects inherit from IForwardObject do I?

I'll give it a shot tommorow.

Interested in Fractals? Check out my App, Fractal Scout, free on the Google Play store.

Yes, you must inherit from C# interfaces to make them work. And you need to have a 'minimal' interface constraint to a generic in order to actually do stuff with the generic beyond object stuff.
Quote:Original post by Nanoha
I like the sound of 2) but I don't have to make my Player etc objects inherit from IForwardObject do I?


You could (you can multiple-inherit from interfaces cleanly in C#).

If you want to decouple things some more you could make a separate class like this (not sure what the name of this pattern is, but I'm guessing it's the degenerate form of Chain of Responsibility):

class PlayerInputForwarder : IInputForwarder{  Player player;  ctor(Player player) { this.player = player; }    // Implement the interface's KeyDown/KeyUp in this class.  // Depending on accesibility you might want to make this a nested class inside the player class.}



I usually only make these kinds of classes during refactoring when one class (such as Player) gets too messy.

This topic is closed to new replies.

Advertisement