我确信有一种聪明的方法可以解决这个问题,但我无法理解这一点。这是场景:
我有一个包含大约30个属性的基类。假设我在这个名为Type的类上有一个属性。对于此类的实例的子集,我想基于Type属性添加一些属性。在这种情况下,当我创建对象时,我可以创建包含这些额外属性的基类的子类。我的问题是用户可以根据组合框更改类型,我需要能够将其强制转换回基类,或者将其更改为具有不同附加属性子集的完全不同的子类。希望这很清楚。关于如何处理这个的任何建议?
注意:这是一个棕色的应用程序,所以虽然一个属性包的想法很有吸引力,但是如果没有重大的痛苦也是不可能的。
答案 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