简体   繁体   English

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

[英]C# generic type argument from child class, possible?

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. 我有一个父类,我想举行一个事件Action,其中T是任何子类继承它的类型。

eg 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 ? 所以问题是,以上可能吗?我将在Parent类中对T使用什么?

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. 我正在研究基于继承的ORM,以防您想知道它的用途。 The NewItem event is raised whenever the ORM inserts data into the database. 每当ORM将数据插入数据库时​​,都会引发NewItem事件。

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. ActiveRecord类驻留在单独的程序集中,而UserRecord驻留在我正在处理的Web项目中。 (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. 事件应将有问题的记录作为参数传递给事件处理程序,因此需要使用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. 但是,当我在基类(ActiveRecord)中声明这些事件时,我需要某种方式将CHILD类型传递给事件处理程序,以便获得强类型的对象。

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. 编辑2:如果需要的话,只是想让您知道反射,动态方法或类似的选项。 However I doubt it for this particular scenario :-( 但是,我对此特定情况表示怀疑:-(

I wouldn't really recommend it, but you could use a C# version of the 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
    }
}

In practice, this will be pretty hard to use sensibly; 实际上,要明智地使用它会非常困难; there must be a better solution to the overall design, in all honesty. 老实说,必须有一个更好的整体设计解决方案。

Try this: 尝试这个:

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

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

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

If you can't make Parent to be abstract , you can add one abstract transition class between Parent and Child . 如果不能使Parentabstract ,可以在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 
    }
} 

Actually I think I just found a much better approach: 实际上,我认为我发现了一种更好的方法:

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

class UserRecord : ActiveRecord
{

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

This seems much more clean to me, so I'll be using that instead. 对我来说,这似乎更干净,所以我将改用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 C# 4.0 中,是否可以从泛型类型参数派生 class? - In C# 4.0, is it possible to derive a class from a generic type parameter? C# 反射 - 从基类中获取超类的通用参数类型 - C# Reflection - Get Generic Argument type of Super class from within the Base class C#从泛型继承的类作为类型 - C# inherited class from generic as a type 是否可以将C#泛型方法类型参数约束为“可从”包含类的类型参数“赋值”? - Is it possible to constrain a C# generic method type parameter as “assignable from” the containing class' type parameter? 如何将子类型传递给父 class C# 中的泛型 - How to pass child type to generic in parent class C# 对于C#,是否可以在泛型类的实例声明中指定类型约束? - For C#, is it possible to specify type constraints in an instance declaration of a generic class? C#仅通过接口访问类型为泛型参数类型的泛型类成员 - C# Access to a generic class member whose type is a generic argument type, only via an interface C#泛型方法类型参数不是从用法推断出来的 - C# generic method type argument not inferred from usage C# 类型到泛型类 - C# Type to Generic class 继承自抽象 class 的泛型 class 类型的 C# - C# type of generic class that inherits from abstract class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM