-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Coretype variables renamed back to netfx counterpart for reflection based serialization #11910
Conversation
@@ -26,7 +26,7 @@ public struct Char : IComparable, IComparable<Char>, IEquatable<Char>, IConverti | |||
// | |||
// Member Variables | |||
// | |||
private char _value; | |||
private char m_value; // Do not rename (binary serialization) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not think it is necessary to rename these to allow binary serialization.
Binary serializers have to treat primitive types like char or byte in special way. They cannot depend on the fields in them. Otherwise, they would end up with infinite recursion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a case where the current names break something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The primitives shouldn't need renames since the serialization format special-cases them. The other changes should still be necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We were hitting a few issues and after the rename they were gone. Could be related to something else, needs more investigation. Due to the fact that we need to finish this for 2.0 we (@morganbr @danmosemsft @stephentoub @krwq) decided to keep the changes on the Primitives.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please share details about the issues that you are hitting that are "fixed" by this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will follow up on your question later...
@stephentoub I've made the EqualityComparers serialize like desktop PTAL. cc: @ViktorHofer |
@@ -401,6 +402,14 @@ internal override int LastIndexOf(T[] array, T value, int startIndex, int count) | |||
} | |||
return -1; | |||
} | |||
|
|||
public void GetObjectData(SerializationInfo info, StreamingContext context) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type needs to implement ISerializable as well, no? Same for the other one. Did this change alone make the tests pass?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, I was just going to send patch with this 😉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ViktorHofer thank @stephentoub 😉
@@ -66,6 +66,7 @@ namespace System.Collections | |||
// | |||
[DebuggerTypeProxy(typeof(System.Collections.Hashtable.HashtableDebugView))] | |||
[DebuggerDisplay("Count = {Count}")] | |||
[Serializable] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not going to work because of it will conflict with public Hashtable in corefx. When deserializing payload from desktop, the binary serializer will not know whether it needs to create this internal Hashtable or public Hashtable in corefx.
What is this needed for? If it is really needed, I think it needs to be fixed by moving the Hashtable from corefx to corelib.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More generally, are we actually exposing this Hashtable from any APIs, e.g. are we returning this from public APIs that return IDictionary? If so, we probably want to move the "real" Hashtable to CoreCLR anyway, to handle existing code that casts the IDictionary to Hashtable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes we are in at least a few cases I just found out. After my build is finished I can tell you the concrete types that are using it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More generally, are we actually exposing this Hashtable from any APIs, e.g. are we returning this from APIs that return IDictionary?
We have been engineering around this problem (e.g. Environment.GetVariables). I agree that we should finally bite the bullet and move Hashtable to CoreLib if there is any reason for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there anything I need to watch out for when moving it from corefx to coreclr?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TimeZone is currently not serializable because of it: https://github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/CurrentSystemTimeZone.Cache.cs#L33
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is it possible that StringDictionary which lives in corefx uses the internal Hashtable from coreclr?
https://github.com/dotnet/corefx/blob/master/src/System.Collections.Specialized/src/System/Collections/Specialized/StringDictionary.cs#L21
Deserialization of type System.Collections.Specialized.StringDictionary failed
System.Runtime.Serialization.Formatters.Tests.BinaryFormatterTests.ValidateTfmHashes(original: [System.Collections.DictionaryEntry, System.Collections.DictionaryEntry], tfmBase64Hashes: [\"AAEAAAD/////AQAAAAAAAAAMAgAAAGFTeXN0ZW0uQ29sbGVjdG\"..., \"AAEAAAD/////AQAAAAAAAAAMAgAAAElTeXN0ZW0sIFZlcnNpb2\"...]) [FAIL]
System.Runtime.Serialization.SerializationException : Type 'System.Collections.Hashtable' in Assembly 'System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' is not marked as serializable.
Or is this already the mixup because I marked both as serializable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
StringDictionary should be using CoreFX's Hashtable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If TimeZone is the only reason for moving HashTable, we could also drop serialization on TimeZone. When I added it to the list, I didn't realize it's obsolete. We do have data showing it used in serialization, but it's rare (~0.001%).
The merge of master did not seem to get done right. The diff shows many unrelated changes that makes it hard to review. Could you please clean it up? |
Yes will do. |
0b82d74
to
4f2b9ec
Compare
done |
|
||
public void GetObjectData(SerializationInfo info, StreamingContext context) | ||
{ | ||
// The LongEnumEqualityComparer does not exist on 4.0 so we need to serialize this comparer as ObjectEqualityComparer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is 4.0 relevant to us?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't matter. Because this code exists in 4.7, the type in 4.7 doesn't have a deserialization ctor, which means core has to do the same dance. The comment could be tweaked if desired, though.
For performance, Lazy was completely rewritten for .NET Core 2.0 and has an entirely different format than desktop; trying to get it to match the desktop serialization format would require either reverting or providing a complicated custom serialization/deserialization implementation to try to match. Lazy can also wrap an Exception that occurred from trying to instantiate the object, and the only exception types that are serializable as of now in core are the base Exception and AggregateException. As such, we're cutting it from the list of supported types in 2.0. An easy workaround is simply to do what the implementation does: serialize lazy.Value instead of lazy.
Merging in this state to unblock 2.0 porting. I"ll follow up with @jkotas offline and we can rename the primitive type members back if necessary. |
…ased serialization (dotnet#11910) * Variables renamed for reflection based serialization * Make EqualityComparers serialize like desktop * add missing interfaces * TimeZone serializable added * Internal hashtable serializable * Removed TimeZone as serializable type * Remove Lazy<T>'s [Serializable] attribute for 2.0 For performance, Lazy was completely rewritten for .NET Core 2.0 and has an entirely different format than desktop; trying to get it to match the desktop serialization format would require either reverting or providing a complicated custom serialization/deserialization implementation to try to match. Lazy can also wrap an Exception that occurred from trying to instantiate the object, and the only exception types that are serializable as of now in core are the base Exception and AggregateException. As such, we're cutting it from the list of supported types in 2.0. An easy workaround is simply to do what the implementation does: serialize lazy.Value instead of lazy. * tiny fixes to equalitycomparer.cs
* Scale back [Serializable] on CoreCLR types (#11765) Removes SerializableAttribute from CoreCLR types not intended to be serializable as well as adding special handling to MulticastDelegate to prevent serializing delegates (which can't be correctly serialized cross platform/runtime). * ISerializable cleanup (#11873) Changes to throw PlatformNotSupportedException from ISerializable.GetObjectData and serialization constructors on non-Serializable types. Also removes private serialization constructors and some unneeded code that was used to support serializing non-serializable types. A few tests testing GetObjectData implementations are also removed. For Exception types, we call base instead of throwing from GetObjectData to be consistent with the many Exceptions that don't override GetObjectData * IDeserializationCallback cleanup Throws PlatformNotSupportedException from IDeserializationCallback and IObjectReference implementations on types that are no longer serializable. * Coretype variables renamed back to netfx counterpart for reflection based serialization (#11910) * Variables renamed for reflection based serialization * Make EqualityComparers serialize like desktop * add missing interfaces * TimeZone serializable added * Internal hashtable serializable * Removed TimeZone as serializable type * Remove Lazy<T>'s [Serializable] attribute for 2.0 For performance, Lazy was completely rewritten for .NET Core 2.0 and has an entirely different format than desktop; trying to get it to match the desktop serialization format would require either reverting or providing a complicated custom serialization/deserialization implementation to try to match. Lazy can also wrap an Exception that occurred from trying to instantiate the object, and the only exception types that are serializable as of now in core are the base Exception and AggregateException. As such, we're cutting it from the list of supported types in 2.0. An easy workaround is simply to do what the implementation does: serialize lazy.Value instead of lazy. * tiny fixes to equalitycomparer.cs * Merge pull request #11995 from ViktorHofer/SerializationFollowUp Internal hashtable serialization attribute removed * Fixes deserializaing TimeZoneInfo by putting back the IDeserializationCallback.OnDeserialization method. (#12024)
Relates to https://github.com/dotnet/corefx/issues/19119
This PR will be merged into the 2.0 branch. See issue above for more details.
cc @krwq