代码之家  ›  专栏  ›  技术社区  ›  Steffen

C子类的泛型类型参数,可能吗?

  •  4
  • Steffen  · 技术社区  · 14 年前

    我想标题并没有说太多,下面是解释。

    我有一个父类,我想保存一个事件操作,其中t是子类继承它的类型。

    例如这样的:

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

    所以问题是,上面的可能吗,在父类中,我会用什么来表示t?

    请注意,我不希望在父类中使用泛型参数,因为这看起来真的很愚蠢,因此会妨碍可读性。

    class UserRecord : ActiveRecord<UserRecord>
    

    我正在开发一个基于继承的ORM,以防您想知道它是用来做什么的。每当ORM向数据库中插入数据时,都会引发NewItem事件。

    编辑:试图澄清一点更好,正确的类命名。

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

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

    但是,当我在基类(ActiveRecord)中声明这些事件时,我需要某种方法将子类型传递给事件处理程序,以便获得强类型对象。

    能够 当然,先执行操作,然后在我的实现中执行类型转换,但这并不是很好:-(

    希望这能解决一点问题,否则请提问:—)

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

    3 回复  |  直到 14 年前
        1
  •  6
  •   Ani    14 年前

    我不太推荐,但你可以使用 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
        }
    }
    

    在实践中,这将是相当难以明智地使用;必须有一个更好的整体设计解决方案,在所有诚实。

        2
  •  0
  •   Cheng Chen    14 年前

    试试这个:

    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 ,您可以在 起源 Child .

    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 
        }
    } 
    
        3
  •  0
  •   Steffen    14 年前

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

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

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