When using Marshal.SizeOf(Type), this gives a warning: "'Marshal.SizeOf(Type)' is obsolete"
Does this make sense? What's the rationale? What is the alternative?
cc @mellinoe
The message (there's also a similar message on SizeOf(Object)) says:
SizeOf(Type) may be unavailable in future releases. Instead, use SizeOf
(). For more info, go to http://go.microsoft.com/fwlink/?LinkID=296515
To me, that argument doesn't sound very persuasive, when you have a Type, calling SizeOf<T>() requires lots of reflection (and might be impossible on .Net Native), so SizeOf(Type) still sounds useful, even in the presence of SizeOf<T>().
I agree with @svick 's reasoning. Obviously the generic overload is similar and can sort-of be used as a replacement, but that's the same story for every method accepting a Type parameter, and we haven't obsolete'd all of those.
@tmds @svick @mellinoe Thanks for bringing this up.
The reason we did the deprecate was because it didn't work very well with AOT scenarios where discovering the incoming type is impossible to get 100% correct, even with advanced flow analysis.
Today we are converging on .NET Core contract - and I agree that it does not make much sense to deprecate the Type version just because of limitation on AOT. We are working on a plan to address this limitation in .NET Native, and we can consider un-deprecate this once it is ready.
Meanwhile, I'd be curious to see what kind of scenarios would require the Type version rather than the T version for interop scenarios, because typically you would work with a known type determined by the native signature. I can imagine there are such cases in framework/engines that are more general-purpose, and I'm interested to see what that looks like.
In any case, we should encourage developers to use the T version as it is more discoverable, explicit, and works better with AOT.
Let's keep this issue open to collect more feedback.
@yizhang82 It happens in reflection use-cases.
@tmds Thanks. I'm looking for more specific real world scenario/examples for this particular API.
@yizhang82 more specific: I use it in (de)serialization to allocate byte arrays of the Marshal.SizeOf reflected types and then Marshal.Copy stuff.
@yizhang82 Am I right when concluding the overload shouldn't be deprecated? Instead, the generic version is recommended when it can be used.
@tmds Thanks. Your deserialization example is very interesting and makes sense. I tend to agree that the overload shouldn't have been deprecated. We are considering un-deprecating this in the future. And yes, using the generic overload is recommended over the non-generic one.
Hi. Just to add, I have similar case with @tmds. I am developing a component which utilizes reflection to detect the field/property type then generate binary array from a class which represent a binary message to send it via Serial port. The component is targeted for Windows IoT.
Because there are numbers of message type, rather than creating manual serializer for each message type, I automate the message generation process using reflection and custom attributes. I also not using struct approach because I need inheritance feature.
Cheers.
Hello, I also have a scenario: when I would like to enumerate all properties of a class and get marshal size of them. See http://stackoverflow.com/questions/38508499/how-do-i-get-marshal-size-of-a-specific-property-from-a-type-in-net-core .
@yizhang82
We are working on a plan to address this limitation in .NET Native, and we can consider un-deprecate this once it is ready.
does this apply only to Marshal.SizeOf(Type type) or to all Marshal methods which have been marked as Obsolete (e.g. PtrToStructure, StructureToPtr, GetDelegateForFunctionPointer)
@joemey Not every obsolete Marshal methods - there are Marshal methods that are obsolete for very good reason. For example, ReadInt32(object, IntPtr). I was mostly talking about Marshal methods that were marked as Obsolete because they were not friendly to AOT. Instead, we are looking at better AOT technology that can handle those APIs in better ways. However, our recommendation is still the same - using the
@yizhang82 I'm not against these changes but please keep in mind that these changes won't be easy to integrate in an existing codebase which has to support pre .net core runtimes.
I'm maintaining a library myself and I can't simply replace a now obsolete method with it's new generic version. I would have to rewrite a good chunk of "low level" code only for .net core because .net core expects us to use the generic API whereas the pre .net core version only has the non generic version.
However, our recommendation is still the same - using the version whenever you can, for better AOT experience.
there is proposal dotnet/corefx#10093 to use a new attribute instead of [Obsolete] to encourage people to not use something. maybe something like this would lower the overall impact of these changes.
@joemey I'm mostly referring to deprecated Marshal API that are deprecated due to a different reason than having new generic versions.
Most helpful comment
The message (there's also a similar message on
SizeOf(Object)) says:To me, that argument doesn't sound very persuasive, when you have a
Type, callingSizeOf<T>()requires lots of reflection (and might be impossible on .Net Native), soSizeOf(Type)still sounds useful, even in the presence ofSizeOf<T>().