C # - How to copy / create an object as a decponent

This is easier to explain with an example. Given these two classes:

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; } } 

Suppose I have a fully created instance of MyClassA (with all properties from AY populated). Then I need to make an instance of MyClassB, which is exactly the same as my instance of MyClassA, but with a filled Property_Z (with a custom value, of course). How can i do this?

Doing this does not work (throws and discards the Cast exception):

 MyClassB myInstanceB = (myClassB) myInstanceA; myInstance.Property_Z = myCustomValue; 

I didn’t have to do anything like this from my C ++ days, and I'm at a dead end.

Any ideas?


UPDATE: I found a solution to my problem in the way I create instances. This is below. I did not mark this as an answer, because it did not quite correspond to my question.

+4
source share
7 answers

Created instance of MyClassA . This is its runtime type, not MyClassB . You cannot use an instance of MyClassA for MyClassB at runtime because MyClassB is a more specific type than MyClassA .

You need to create a completely new instance of MyClassB . One way to clear this up is to create a constructor that accepts MyClassA , for example

 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; } } 
+5
source

You can use Reflection to copy the properties of the base class, as shown 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
source

Simple answer:

 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; } } 

Use it as follows:

 MyClassB o = new MyClassB(instanceOfMyClassA); o.Property_Z = whatever; 
+2
source

Looks like you're looking for a free copy constructor. C # does not provide one ( http://msdn.microsoft.com/en-us/library/ms173116%28VS.80%29.aspx ), but you can do this quite easily using Object.MemberwiseClone or the BinaryFormatter serializer ( http : //www.codeproject.com/KB/tips/SerializedObjectCloner.aspx ). Take care whether you want a shallow copy or a deep copy.

+2
source

You can define an explicit or implicit conversion from MyClassA to MyClassB and use the syntax you provide.

 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; } } 
+1
source

What about:

  • Create a base class that implements IClonable and has all row properties from A to D and Z.
  • Create an instance of this class for MyClassA.
  • Create an instance of MyClassB by cloning MyClassA.
  • Set the Z property to MyClassB.
0
source

Here is what I did:

I created my own method, which creates and sets all properties (AY) that use type parameters. It looks like this:

 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 } 

Since the type parameter can be a type that is descended from the restriction, I can pass MyClassB objects and get them just like myClassA.

Then I can do any as needed.

 MyClassA myInstanceA = MakeAMyClass<MyClassA>(somethingToSetFrom); MyClassB myInstanceB = MakeAMyClass<MyClassB>(somethingToSetFrom); myInstanceB.Property_Z = someotherValue; 

Allows me to avoid having to use a method to copy all properties from MyClassA to MyClassB.

0
source

Source: https://habr.com/ru/post/1303300/


All Articles