用于向基类添加属性的设计模式

时间:2009-11-25 23:15:12

标签: .net design-patterns oop

我确信有一种聪明的方法可以解决这个问题,但我无法理解这一点。这是场景:

我有一个包含大约30个属性的基类。假设我在这个名为Type的类上有一个属性。对于此类的实例的子集,我想基于Type属性添加一些属性。在这种情况下,当我创建对象时,我可以创建包含这些额外属性的基类的子类。我的问题是用户可以根据组合框更改类型,我需要能够将其强制转换回基类,或者将其更改为具有不同附加属性子集的完全不同的子类。希望这很清楚。关于如何处理这个的任何建议?

注意:这是一个棕色的应用程序,所以虽然一个属性包的想法很有吸引力,但是如果没有重大的痛苦也是不可能的。

5 个答案:

答案 0 :(得分:2)

只需要一个属性列表......

List<Properties> MyProps;

并适当添加。

答案 1 :(得分:2)

如果您从经过修改的 factory pattern开始,您可以这样做。

我创建了一个基类,每当Type属性因用户输入而改变时,factory-ish类(我称之为Bob)负责返回指定类型的类。您将调用Bob,传入类型和当前对象,Bob将返回特定的子类型。

例如:

public class MyBase
{
    public string Type { get; set; }
    public string CommonProperty { get; set; }
}

public class ExtendedClass : MyBase
{
    public string ExtraProperty { get; set; }
}

public static class MyNotFactory
{
    public static MyBase Create(MyBase baseObject)
    {
        switch (baseObject.Type)
        {
            case "Extended":
                return baseObject as ExtendedClass;
                break;
            default:
                return baseObject;
                break;
        }
    }
}

(注意:我没有检查过代码)

编辑:你知道......现在我把它放在代码中并不是真正的工厂模式......我已经重命名了。

答案 2 :(得分:1)

我喜欢设计模式和下一个人一样,但我认为你在这里看到的只是简单的旧.NET继承和一点反思。

我会根据您的需要创建继承层次结构,使用正常的继承,然后查看Activator.CreateInstance(或基类上的静态工厂方法)来创建对象的实例。

答案 3 :(得分:0)

在.Net(和其他强类型的静态语言)中,一旦实例化了类的实例,就无法将该实例更改为其他类型。

“更改类型”的唯一方法是为变量分配兼容类型的不同实例(如果变量将接受实现Foo的类型,并且类型Foo1和Foo2都实现/扩展Foo然后可以将一个实例分配给变量

如果您希望在此转换中维护一些状态,您可以为对象的一个​​实例定义一种通用方法,以从另一个兼容实例复制所有相关值(如果字段/可能通过反射属性具有相同的类型和名称)或者通过委托可以轻松共享子节,但这是一种危险的做法,除非您的设计结构从不关心,否则子节类型不是不可变的。

你的问题听起来很像你喜欢以下内容:

class FooWithAdOns
{
    int Blah { get; set;}
    int Wibble { get; set }
    Type AddOn { get; set; }
    /* if AddOn type is AddOnX */
    int X { get; set; }
    /* if AddOn type is AddOnY */
    int Y { get; set; }
}

class AddOnX
{
    int X { get; set;}
}


class AddOnY
{
    int Y { get; set;}
}

FooWithAddOn上是否存在X / Y是动态的。

有两种方法可以实现这一点,现在有一种可能,但仅限于基于使用ITypedList之类的反射的UI交互。 另一个功能强大得多,但它基于动态分派的c#4.0特性,其中方法/属性的名称在运行时得出。

如果您只是通过像PropertyGrid之类的东西与UI进行交互,那么第一种方法就可以工作,只要每次列出属性更改您重建属性网格,后者将在代码中完美地工作,但是,对于UI代码,您需要编写一个包装器,它能够完成ITypedList所做的大部分操作,以便将当前的“虚假属性”暴露给反射UI。

答案 4 :(得分:0)

谢谢大家的回答。最后我找到了这篇文章:"Using reflection to copy base class properties"

我稍微修改了这个帖子,最后将其作为我的工作解决方案。 (在我的例子中,我创建了一个名为Base的类,并有一些派生自它的类):

  Private Shared Sub CopyBaseProperties(ByVal pSource As Base, ByVal pDestination As Base)

      Dim fields() As FieldInfo = GetType(Base).GetFields(BindingFlags.NonPublic Or BindingFlags.Public Or BindingFlags.Instance)
      For Each tmpField As FieldInfo In fields
         tmpField.SetValue(pDestination, tmpField.GetValue(pSource))
      Next

   End Sub