来自子类的C#泛型类型参数可能吗?

时间:2010-11-27 09:48:48

标签: c# generics

我想标题并没有真正说明,所以这是解释。

我有一个父类,我希望保存一个事件Action,其中T是子类继承它的类型。

e.g。像这样的东西:

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.
  }
}

所以问题是,上面是否可能,以及在Parent类中我将使用什么?

请注意,我不希望我的父类有一个泛型参数,因为它真的看起来很愚蠢,因而妨碍了它的可读性。

class UserRecord : ActiveRecord<UserRecord>

我正在研究基于继承的ORM,以防你想知道它是什么。只要ORM将数据插入数据库,就会引发NewItem事件。

编辑:尝试通过正确命名类来更好地阐明。

ActiveRecord类驻留在一个单独的程序集中,UserRecord驻留在我正在处理的Web项目中。 (注意:我是两个部分的开发者,但它是两个独立的项目)

我希望能够在成功插入行,删除行等时引发事件。事件应该将有问题的记录作为参数传递给事件处理程序,因此需要Action。

然而,当我在基类(ActiveRecord)中声明这些事件时,我需要一些方法将CHILD类型传递给事件处理程序,以获得强类型对象。

当然可以进行Action,然后在我的实现中进行类型转换,但这真的不太好: - (

希望这会解决一些问题,否则请问: - )

编辑2:只是想让你知道反思,动态方法或类似的东西是一个选项,如果这有帮助的话。但是我对这种特殊情况表示怀疑: - (

3 个答案:

答案 0 :(得分:6)

我不是真的推荐它,但你可以使用curiously recurring template pattern的C#版本:

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
    }
}

在实践中,这将非常难以合理使用;诚然,必须有更好的解决方案来整体设计。

答案 1 :(得分:0)

试试这个:

abstract class Parent<T>
{
    public event Action<T> NewItem;
}

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

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

如果您无法将Parent设为abstract,则可以在ParentChild之间添加一个抽象过渡类。

class Parent<T>
{    
    public event Action<T> NewItem;
}

abstract class Transition<T> : Parent<T> { }

class Child : Transition<Child>
{
    public Child()
    {
        NewItem += OnNewItem;
    }
    private void OnNewItem(Child obj)
    {
        // Do something 
    }
} 

答案 2 :(得分:0)

实际上我觉得我刚刚找到了一个更好的方法:

abstract class ActiveRecord
{
  protected virtual void OnNewItem() {}
}

class UserRecord : ActiveRecord
{

  protected override void OnNewItem()
  {
    // Still got the UserRecord object, now it's just "this"
  }
}

这对我来说似乎更加干净,所以我会改用它。