Open sdfreyder opened 8 years ago
Yes, that's a known limitation. Doing a runtime type check on every cloned object would make the entire cloning process quite slow. I think it would be worth adding as an opt-in functionality though (an extra Boolean
flag on GetClone
method.
I might get on that soon, but if you feel like you'd be able to contribute that change I'm happy to accept a Pull Request.
I think we got the cloning of the runtime-defined type to work but ultimately the problem that stopped us was the fact that the expression-tree-generated code wasn't able to assign to private members/fields.
I can see how that might be a problem. I think it should still be possible to use CloneExtensions to copy the public members using a custom initializer logic provided in initialize dictionary. I'll add something to the documentation when I have a moment later today.
Oh yes - that works very nicely. We got the cloning to work fine with public members and using (as I recall) Activator.CreateInstance (and therefore not requiring the dictionary), but for our use-case, it turned out that not being able to clone the the private members was a complete show-stopper. I seems clear that private members can be copied using either Reflection, or Reflection.Emit-generated code, but not by Expression-trees, I don't know why.
You can set private members using Expressions but you need to use the FieldInfo or PropertyInfo fetched from the class via reflection. Particularly, these overloads:
public static MemberExpression Field(Expression expression, FieldInfo field); public static MemberExpression Property(Expression expression, PropertyInfo property)
Next
time I get some spare cycles I shall look into that - thanks for
the info Marcin.
On 8/13/2017 9:00 AM, deipax wrote:
You can set private members using Expressions but you need to
use the FieldInfo or PropertyInfo fetched from the class via
reflection. Particularly, these overloads:
public static MemberExpression Field(Expression expression,
FieldInfo field);
public static MemberExpression Property(Expression expression,
PropertyInfo property)
—
You are receiving this because you authored the thread.
Reply to this email directly, view
it on GitHub, or mute
the thread.
{"api_version":"1.0","publisher":{"api_key":"05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":{"external_key":"github/MarcinJuraszek/CloneExtensions","title":"MarcinJuraszek/CloneExtensions","subtitle":"GitHub repository","main_image_url":<a class="moz-txt-link-rfc2396E" href="https://cloud.githubusercontent.com/assets/143418/17495839/a5054eac-5d88-11e6-95fc-7290892c7bb5.png">"https://cloud.githubusercontent.com/assets/143418/17495839/a5054eac-5d88-11e6-95fc-7290892c7bb5.png"</a>,"avatar_image_url":<a class="moz-txt-link-rfc2396E" href="https://cloud.githubusercontent.com/assets/143418/15842166/7c72db34-2c0b-11e6-9aed-b52498112777.png">"https://cloud.githubusercontent.com/assets/143418/15842166/7c72db34-2c0b-11e6-9aed-b52498112777.png"</a>,"action":{"name":"Open in GitHub","url":<a class="moz-txt-link-rfc2396E" href="https://github.com/MarcinJuraszek/CloneExtensions">"https://github.com/MarcinJuraszek/C
loneExt ensions"}},"updates":{"snippets":[{"icon":"PERSON","message":"@deipax in #7: You can set private members using Expressions but you need to use the FieldInfo or PropertyInfo fetched from the class via reflection. Particularly, these overloads:\r\n\r\npublic static MemberExpression Field(Expression expression, FieldInfo field);\r\npublic static MemberExpression Property(Expression expression, PropertyInfo property)\r\n"}],"action":{"name":"View Issue","url":"https://github.com/MarcinJuraszek/CloneExtensions/issues/7#issuecomment-322043937"}}}
Cloning of objects where runtime type is not declared type does not seem to work if the declared type is an abstract or interface type. Fails with error "You have to provide initialization expression for
When cloning objects whose runtime time differs from the declared type (as would be the case with a derived type using polymorphism) the resulting object is of the declared (less-derived) type instead of the runtime (derived) type.
The attached zip contains a short test program which demonstrates the issue.
clonetest.zip