Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# generic type argument from child class, possible?

Tags:

c#

generics

I guess the title doesn't really say a lot, so here's the explanation.

I have a parent class, which I want to hold an event Action, where T is the type of whatever child class inherits it.

e.g. something like this:

abstract class ActiveRecord
{
  protected event Action<T> NewItem;
}

class UserRecord : ActiveRecord
{
  public UserRecord()
  {
    NewItem += OnNewItem; // NewItem would in this case be Action<UserRecord>
  }

  private void OnNewItem(UserRecord obj)
  {
    // Flush cache of all users, since there's a new user in the DB.
  }
}

So the question is, is the above possible, and what would I use for T in the Parent class ?

Note that I don't want a generic argument to my parent class, since that'd really look stupid, and thus hinder the readability.

class UserRecord : ActiveRecord<UserRecord>

I'm working on an inheritance based ORM, in case you wonder what it's for. The NewItem event is raised whenever the ORM inserts data into the database.

Edit: Trying to clarify a bit better, with correct naming of the classes.

The ActiveRecord class resides in a separate assembly, and the UserRecord resides in a web project I'm working on. (Note: I'm the developer of both parts, however it's two separate projects)

I want to be able to raise events upon succesfully inserting a row, deleting a row, and so forth. The events should pass the record in question as argument to the event handler, hence the need for Action.

However as I'm declaring these events in the base class (ActiveRecord), I need some way to pass the CHILD type to the event handlers, in order to get a strongly typed object.

I could of course go Action and then do a typecast in my implementation, but that really wouldn't be very nice :-(

Hope this clears up the question a bit, otherwise please ask :-)

Edit 2: Just wanted to let you know reflection, dynamic methods or anything similar is an option, if that'd help. However I doubt it for this particular scenario :-(

like image 456
Steffen Avatar asked Nov 27 '10 09:11

Steffen


1 Answers

I wouldn't really recommend it, but you could use a C# version of the curiously recurring template pattern:

class Parent<T> where T : Parent<T>
{
    protected event Action<T> NewItem;
}


class Child : Parent<Child>
{
    public Child()
    {
        NewItem += OnNewItem;
    }

    private void OnNewItem(Child obj)
    {
        // Do something
    }
}

In practice, this will be pretty hard to use sensibly; there must be a better solution to the overall design, in all honesty.

like image 183
Ani Avatar answered Sep 18 '22 07:09

Ani