通过示例更容易解释。鉴于这两个类:
public class MyClassA
{
public String Property_A { get; set; }
public String Property_B { get; set; }
public String Property_C { get; set; }
public String Property_D { get; set; }
...
public String Property_Y { get; set; }
}
public class MyClassB: MyClassA
{
public String Property_Z { get; set; }
}
假设我已经完全创建了MyClassA的实例(填充了A - Y中的所有属性)。然后我需要创建一个MyClassB的实例,它与我的MyClassA实例完全相同,但填入了Property_Z(当然是自定义值)。我怎么能这样做?
执行此操作无效(抛出和无效的强制转换异常):
MyClassB myInstanceB = (myClassB) myInstanceA;
myInstance.Property_Z = myCustomValue;
自从我的C ++时代起,我就不需要做任何这样的事了。我很难过。
有什么想法吗?
更新:我找到了解决我如何创建实例的问题。它在下面。我没有把它标记为答案,因为它不完全适合我的问题。
答案 0 :(得分:5)
您创建的实例是MyClassA
。那是它的运行时类型,而不是MyClassB
。您无法在运行时将MyClassA
实例强制转换为MyClassB
,因为MyClassB
是一种比MyClassA
更具体的类型。
您需要创建MyClassB
的全新实例。清理它的一种方法是创建一个带MyClassA
的构造函数,例如
public class MyClassB : MyClassA
{
public MyClassB(MyClassA a, string z)
{
this.PropertyA = a.PropertyA;
this.PropertyB = a.PropertyB;
// etc.
this.PropertyZ = z;
}
public string PropertyZ { get; set; }
}
答案 1 :(得分:2)
您可以使用Reflection来复制基类属性,如图所示here。
public void Update(MyObject o)
{
MyObject copyObject = ...
Type type = o.GetType();
while (type != null)
{
UpdateForType(type, o, copyObject);
type = type.BaseType;
}
}
private static void UpdateForType(Type type, MyObject source, MyObject destination)
{
FieldInfo[] myObjectFields = type.GetFields(
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
foreach (FieldInfo fi in myObjectFields)
{
fi.SetValue(destination, fi.GetValue(source));
}
}
答案 2 :(得分:2)
直截了当的答案:
public class MyClassA
{
public String Property_A { get; set; }
public String Property_B { get; set; }
public String Property_C { get; set; }
public String Property_D { get; set; }
...
public String Property_Y { get; set; }
}
public class MyClassB: MyClassA
{
public MyClassB(MyClassA copy)
{
Property_A = copy.PropertyA;
Property_B = copy.PropertyB;
...
}
public String Property_Z { get; set; }
}
像这样使用:
MyClassB o = new MyClassB(instanceOfMyClassA);
o.Property_Z = whatever;
答案 3 :(得分:2)
听起来你正在寻找一个免费的拷贝构造函数。 C#不提供一个(http://msdn.microsoft.com/en-us/library/ms173116%28VS.80%29.aspx),但您可以使用Object.MemberwiseClone
或BinaryFormatter序列化程序(http://www.codeproject.com/KB/tips/SerializedObjectCloner.aspx)轻松完成。注意要知道是否需要浅拷贝或深拷贝。
答案 4 :(得分:1)
您可以定义从MyClassA到MyClassB的显式或隐式强制转换,并使用您提供的语法。
public class MyClassB : MyClassA
{
public String Property_Z { get; set; }
public static explicit operator MyClassB(MyClassA a)
{
MyClassB b = new MyClassB();
b.Property_A = a.Property_A;
/* ... */
b.Property_Y = a.Property_Y;
return b;
}
}
答案 5 :(得分:0)
怎么样:
答案 6 :(得分:0)
这是我最终做的事情:
我创建了我的方法,用于创建和设置使用类型参数的所有属性(A-Y)。它看起来像这样:
public T MakeAMyClass<T>(AnotherClass
where T: MyClassA : new()
{
T returnValue = new T();
T.Property_A = somethingToSetFrom.MakeAPropertyA();
// Fill in the rest of the properties
}
因为类型参数可以是来自约束的类型,所以我能够传入MyClassB对象并使它们与myClassA相同。
然后我可以根据需要制作任何一个。
MyClassA myInstanceA = MakeAMyClass<MyClassA>(somethingToSetFrom);
MyClassB myInstanceB = MakeAMyClass<MyClassB>(somethingToSetFrom);
myInstanceB.Property_Z = someotherValue;
让我避免使用方法将所有属性从MyClassA复制到MyClassB。