派生子类的集合

发布于 2024-10-03 17:52:50 字数 989 浏览 3 评论 0原文

是否存在一种可接受的方法,可以将可能派生的对象添加到集合中,而不允许自行创建基对象或派生对象的实例?我认为这几乎是一个自相矛盾的说法。

关于我能够想到的唯一方法是从子对象的基本实现添加到父集合,如下所示:

// Child constructors
private void Child() { }
protected void Child(Parent parent)
{
    parent.Collection.Add(this);
}

这强制子对象始终使用父对象实例化,但这似乎是一个相当混乱的实现将子类添加到子类的父集合中。我知道我可以将类型类型变量传递给方法,这可能是可行的方法,但我不确定如何创建/转换为传递的类型。


更新:我正在使用看起来像这样的代码作为可能的通用 ChildCollection.Add 方法,以防万一这可以让任何人更好地了解我想要的内容......我们将看看它是否能长期工作:

// Currently testing directly in Parent class;
// can later be moved/modified for Parent's ChildCollection class.
public Child AddTest(string info, Type derivedType)
{
    ConstructorInfo ci = derivedType.GetConstructor(new Type[] { typeof(Parent) });
    Child myBaby = (Child) ci.Invoke(new Object[] { this });
    myBaby.Initialize(info);
    return myBaby;
}

这然后可以使用如下代码进行调用:

Child newChild = Parent.AddTest("Hello World", typeof(DerivedChild));

Is there an accepted method of adding possibly-derived objects to a collection without allowing instances of the base or derived objects to be created on their own? I'm thinking that's almost a contradiction in terms.

About the only method I've been able to come up with is to add to the parent collection from the child's base implementation like this:

// Child constructors
private void Child() { }
protected void Child(Parent parent)
{
    parent.Collection.Add(this);
}

This forces the child object to always be instantiated with a parent, but it seems like a rather messy implementation to add a child class to a parent collection from the child. I know I can pass a Type-type variable to a method, and this might be the way to go, but I'm not sure how to create/cast to the passed type.


Update: I'm playing around with code that looks like this as a possible generic ChildCollection.Add method, in case this gives anybody a better picture of what I want...we'll see if it works in the long run:

// Currently testing directly in Parent class;
// can later be moved/modified for Parent's ChildCollection class.
public Child AddTest(string info, Type derivedType)
{
    ConstructorInfo ci = derivedType.GetConstructor(new Type[] { typeof(Parent) });
    Child myBaby = (Child) ci.Invoke(new Object[] { this });
    myBaby.Initialize(info);
    return myBaby;
}

This could then be called with code like:

Child newChild = Parent.AddTest("Hello World", typeof(DerivedChild));

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

阳光①夏 2024-10-10 17:52:50

最终,我选择了与我在更新中发布的代码非常相似的代码。我将其发布在这里,因为我认为这对于通用对象工厂或有限对象工厂(在本例中,仅限于从 Child 类派生的对象工厂)来说都是一种有用的技术。

基本思想是创建一个自定义集合,然后使用 Add 方法(或者也许我应该将其命名为 Create?)来实例化该对象并正确处理 Child 派生中的任何重写初始化。

这是我最终得到的代码框架:

// Use standard Child
public Child Add(string initInfo)
{
    Child newChild = new Child(this.Parent);
    // There's actually a bit more coding before Initialize()
    // in the real thing, but nothing relevant to the example.
    newChild.Initialize(initInfo);
    List.Add(newChild);
    return newChild;
}

// Overload for derived Child.
public Child Add(Type childDerivative, string initInfo)
{
    if (!childDerivative.IsSubclassOf(typeof(Child)))
        throw new ArgumentException("Not a subclass of Child.");
    ConstructorInfo ci = childDerivative.GetConstructor(
        BindingFlags.Instance |
        BindingFlags.Public | BindingFlags.NonPublic |
        BindingFlags.FlattenHierarchy |
        BindingFlags.ExactBinding, 
        null, new Type[] { typeof(Parent) }, null);
    if (ci == null)
        throw new InvalidOperationException("Failed to find proper constructor.");
    newChild = (Child)ci.Invoke(new Object[] { this.Parent });
    newChild.Initialize(initInfo);
    List.Add(newChild);
    return newChild;
}

由于这可能无法涵盖客户端应用程序可能想要创建的所有可能的派生子级(特别是如果它们将自己的参数添加到构造函数中),我想我可能会还提供了一个 Add(Child child) 方法,但需要注意的是,如果用户使用标准的“new Child(Parent)”实例化 Child 对象,他们还负责以预期的方式执行所有标准初始化步骤。

Ultimately, I've gone for code very similar to what I posted in my update. I'm posting it here, as I think it's a useful technique for either a generic object factory or a limited one (in this case, limited to those that derive from the Child class).

The basic idea is to create a custom collection, then use an Add method (or perhaps I should name it Create?) to instantiate the object and properly handle any overridden initialization in a Child derivative.

Here's a skeleton of the code I ended up with:

// Use standard Child
public Child Add(string initInfo)
{
    Child newChild = new Child(this.Parent);
    // There's actually a bit more coding before Initialize()
    // in the real thing, but nothing relevant to the example.
    newChild.Initialize(initInfo);
    List.Add(newChild);
    return newChild;
}

// Overload for derived Child.
public Child Add(Type childDerivative, string initInfo)
{
    if (!childDerivative.IsSubclassOf(typeof(Child)))
        throw new ArgumentException("Not a subclass of Child.");
    ConstructorInfo ci = childDerivative.GetConstructor(
        BindingFlags.Instance |
        BindingFlags.Public | BindingFlags.NonPublic |
        BindingFlags.FlattenHierarchy |
        BindingFlags.ExactBinding, 
        null, new Type[] { typeof(Parent) }, null);
    if (ci == null)
        throw new InvalidOperationException("Failed to find proper constructor.");
    newChild = (Child)ci.Invoke(new Object[] { this.Parent });
    newChild.Initialize(initInfo);
    List.Add(newChild);
    return newChild;
}

Since this may not cover every possible derived Child the client application might want to create (particularly if they're adding their own parameters to the constructor), I'm thinking I'll probably also provide an Add(Child child) method, with the caveat that if the user is instantiating the Child object with a standard "new Child(Parent)", they're also responsible for taking all the standard initialization steps in the expected manner.

獨角戲 2024-10-10 17:52:50

如果您真的不想创建父类型的实例,只需将其构造函数设置为受保护或将其声明为抽象即可。

然后,您可以轻松创建子类实例并将它们添加到列表中,而无法创建基类的实例。

If you were serious about not needing to be able to CREATE instances of the parent type, just make its constructor protected or declare it abstract.

Then, you can create subclass instances and add them to a list easily, and it will be impossible to create instances of the base class.

夏雨凉 2024-10-10 17:52:50

限制是子对象不应在没有父对象的情况下存在。如何公开“IsAttached”或“Parent”等属性并使用内部方法将子对象附加到父对象?然后,可以在代码库中的任何位置构造子对象,但在附加之前不会成为有效的子对象。

- internal Attach(parent) 
- internal Detach() 
- public IsAttached

然后,父集合可以实现方法来添加子对象并执行一些验证。我正在沿着表单和控件的思路思考。

Collection.Add(child) 
{
    // throw error if the child is not the right type
    child.Attach(this)
    base.add(child)    
} 

The restriction is that a child object shouldn't exist without the parent. How about exposing a property like "IsAttached" or "Parent" and use internal methods to attach child objects to the parent? Then the child objects can be constructed anywhere in your code base but won't be a valid child object until attached.

- internal Attach(parent) 
- internal Detach() 
- public IsAttached

The parent collection can then implement methods to add child objects and perform some validation. I'm thinking along the lines of Forms and Controls.

Collection.Add(child) 
{
    // throw error if the child is not the right type
    child.Attach(this)
    base.add(child)    
} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文