Let's say you start off with this stub:
[<Serializable>]
type Bounderizer =
val mutable _boundRect : Rectangle
new (boundRect : Rectangle) = { _boundRect = boundRect ; }
new () = { _boundRect = Rectangle(0, 0, 1, 1); }
new (info:SerializationInfo, context:StreamingContext) =
{ // to do
}
interface ISerializable with
member this.GetObjectData(info, context) =
if info = null then raise(ArgumentNullException("info"))
info.AddValue("BoundRect", this._boundRect)
// TODO - add BoundRect property
The issue is that the spec says, "In general, this constructor should be protected if the class is not sealed." F# doesn't have a protected keyword - so how do I do this?
Constraints (due to a requirement to match perfectly existing C# classes at the API level):
- Must implement ISerializable
- Constructor must be protected
EDIT - interesting extra information The F# spec says that if you override a protected function that the resulting function will be protected. This is incorrect. If you don't specify accessibility, the resulting override will be public no matter what (breaking the contract).
It is not possible to do this currently using the language as is. It is possible to do this and I have two ways.
The first is to run the output assembly through ILDASM, regex to the method declaration you want, change 'public' to 'family' in the method you want, then ILASM it back. Ewwwww.
The second, which I'm investigating, is to tag the methods with
then write a filter with CCI to change the accessibility on all methods than have the ProtectedAttribute and then remove the attribute. This seems less unseemly than running a regex over the file, but my security settings at work seriously hates the CCI project source, so I can't successfully fetch/decompress/built it.
EDIT - Here is my solution - I tried CCI, but it's not ready for the task. I ended up using Cecil and ended up with the following code:
First an attribute in F#
open System
then the following app which is a client of Cecil:
finally, decorate the methods you want to be protected with MyProtectedAttribute and run the C# app as a post-build step.
in fact protected modifier is not enforcement, but a recommendation
So this should work:
Unfortunately, there is no way - F# does not have protected members. We will consider this in future versions.