-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixed serialization of exceptions without the default constructor (#64). #76
Conversation
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.
A minor optimization change to be made, beside that it looks good 👍
var className = stream.ReadString(session); | ||
var message = stream.ReadString(session); | ||
var remoteStackTraceString = stream.ReadString(session); | ||
var stackTraceString = stream.ReadString(session); | ||
var innerException = stream.ReadObject(session); | ||
|
||
var exception = hasDefaultConstructor ? Activator.CreateInstance(type) : | ||
FormatterServicesGetUninitializedObject(type); |
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 don't need this check here - it's not like having default constructor or not will change depending on the binary payload ;) You can move this check outside the deserializer function i.e:
Func<Object> initialize = hasDefaultConstructor
? (() => Activator.CreateInstance(type))
: (FormatterServicesGetUninitializedObject(type));
or (without measures I'm not sure which one is faster):
Func<Type, Object> initialize = hasDefaultConstructor
? Activator.CreateInstance
: FormatterServicesGetUninitializedObject;
and use initialize
inside deserializer.
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.
But now it introduces unnecessary delegate allocation.
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 happens once per exception type, while constructor check will happen once per each object deserialization call. In practice to be 100% sure, we'd need to check both approaches in performance test - I'll be happy to do that once #57 will finally get merged.
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're right, thanks for the suggestion.
@Horusiath does this look ok to you now? |
Using
FormatterServices.GetUninitializedObject
instead ofActivator.CreateInstance
for exception types that don't have a parameterless constructor.Reflection-based invocation of
GetUninitializedObject
can be removed once the API is exposed in dotnet core API. See this thread for more info: https://github.com/dotnet/corefx/issues/8133