-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Conversation
|
||
private DBNull(SerializationInfo info, StreamingContext context) | ||
{ | ||
throw new NotSupportedException(SR.NotSupported_DBNullSerial); |
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.
need to add the string
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.
oh, it's already there by mistake...
{ | ||
if (info == null) | ||
throw new ArgumentNullException(nameof(info)); | ||
Contract.EndContractBlock(); |
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 don't think we're bothering with these
Please, trim it down. That's lot of unnecessary code. |
I'm also for trimming it down. Thanks |
switch (_unityType) | ||
{ | ||
case EmptyUnity: | ||
{ |
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.
not sure the indents are right
I should have clarified that I didn't expect a code review but more the answer if I should trim it down. @danmosemsft please wait with commenting on code :) |
#endif | ||
class UnitySerializationHolder : ISerializable, IObjectReference | ||
{ | ||
internal const int EmptyUnity = 0x0001; |
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 don't use any of these save NullUnity, and don't plan to use them either. If we remove all the others, a bunch of other code could be removed from this file, and it would still be compatible?
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 would do that, would cut this file in half
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.
Agreed, though it begs the question as to whether any have any short-term benefits in including, because of dependencies elsewhere that are blocked similarly to how the DBNull case blocks some. (Any longer term benefits can be decided on later).
8aca216
to
6dd7394
Compare
That's the trimmed down version of it. We will need a manual typeforward for the UnitySerializationHolder here https://github.com/dotnet/corefx/blob/master/src/shims/manual/mscorlib.forwards.cs#L7 in corefx and tests here https://github.com/dotnet/corefx/blob/master/src/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs#L239 And I'm not 100% sure if this really should remain in coreclr or just go into corefx near System.Data.Common. |
|
||
_unityType = info.GetInt32(UnityTypeName); | ||
_data = info.GetString(DataName); | ||
_assemblyName = info.GetString(AssemblyNameName); |
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 seems like more work than is necessary if looked at in isolation. Maybe a comment that it's for compatibility might help someone confused by that.
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.
You could also remove the fields. There's no real need to read or store those values are written out for backward compat.
Seems DBNull has to stay in corelib because of various magic for it in Convert etc. So it would be tricky to move this new class up. Does not seem worth it. |
6dd7394
to
db966f6
Compare
#if CORECLR | ||
internal | ||
#else | ||
public // On CoreRT, this must be public because of the Reflection.Core/CoreLib divide and the need to whitelist past the ReflectionBlock. |
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.
Now that this is only used for DBNull, it no longer needs to be public
on CoreRT.
_assemblyName = info.GetString(AssemblyNameName); | ||
} | ||
|
||
public virtual 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.
It looks weird for these methods to be marked "virtual" - makes it look like you're expecting someone to override them even though this class has no subtypes.
I wasn't sure about that but will believe you :) |
What I'm still not sure is this: Netfx code of UnitySerilizationHolder. On serialization it first saves the data (string) https://referencesource.microsoft.com/#mscorlib/system/unityserializationholder.cs,137 and after that the UnityType (int). Does that make any sense? Am I missing something? |
Hmm, you have a point. We don't need it to be public for Reflection.Core's sake, but I guess the binary formatter would still need to be able to find the class via Reflection. So I guess we still need the ifdef - just edit the comment to delete the part about Reflection.Core. |
public object GetRealObject(StreamingContext context) | ||
{ | ||
// We are always returning the same DBNull instance and ignoring serialization input. | ||
|
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 we're still trying to be compatible with legacy blobs, should we at least throw if "UnityType" isn't NullUnity
?
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 definitely should throw as otherwise users would just get a random object. But before I can do that I need to verify the weird behavior I posted above. Thanks!
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 SerializationInfo isn't an ordered list - it's a dictionary of name-value pairs. So there's no problem.
Ordering doesn't matter, so it was probably just whatever order for each seemed most convenient at the time. |
Aaah yes I overlooked that. Seems I spent too much time with simple serializable types :D |
I think it should be fine now. PTAL |
/// UnitySerializationHelper should return from a call to GetObjectData. It contains | ||
/// the unityType (defined above) and any optional data (used only for the reflection types). | ||
/// </summary> | ||
public static void GetUnitySerializationInfo(SerializationInfo info, int unityType, string data, Assembly assembly) |
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.
GetUnitySerializationInfo
can be made internal and the "data" and "assembly" parameters serve no purpose anymore.
Aside from that, LGTM.
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.
forget my comment. was wrong.
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.
Why wouldn't DBNull
be able to access it? It lives in the same assembly as UnitySerializationHolder
.
Thanks for the review. @danmosemsft do you also want to review again? :) |
// We are only support deserializing DBNull and throwing for everything else. | ||
if (_unityType != NullUnity) | ||
{ | ||
throw new ArgumentException(SR.Argument_InvalidUnity); |
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.
Invalid Unity type.
is not going to be a helpful message when deserialization fails of a perfectly good .NET Framework blob. How about Type '{0}' is not deserializable.
where you get {0} from Data if it's avaialable else UnityType?
{ | ||
/// <summary> | ||
/// Holds Null class for which we guarantee that there is only ever one instance of. | ||
/// This only exists for backwarts compatibility with |
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.
backwarts is a new word .. and the sentence isn't complete
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.
You'll want to run tests vs desktop blobs - including one that contains something like a serialized Assembly so it exercises the unexpected unity type path
@@ -53,7 +56,7 @@ public object GetRealObject(StreamingContext context) | |||
// We are only support deserializing DBNull and throwing for everything else. | |||
if (_unityType != NullUnity) | |||
{ | |||
throw new ArgumentException(SR.Argument_InvalidUnity); | |||
throw new ArgumentException(SR.Format(SR.Argument_InvalidUnity, _data ?? "UnityType")); |
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.
throw new ArgumentException(SR.Format(SR.Argument_InvalidUnity, _data ?? _unityType ?? "UnityType"));
LGTM |
It would be nice to get this into 2.0.2. But we may not have both sides in in time. |
The corefx changes are already ready to push but I want to wait till my build is finished. |
…lization Make DBNull serializable Signed-off-by: dotnet-bot <[email protected]>
…lization Make DBNull serializable Signed-off-by: dotnet-bot <[email protected]>
Make DBNull serializable
Relates to https://github.com/dotnet/corefx/issues/23398
cc @JonHanna