I'm not sure what the current interop plan for F# is with init only properties in general is?
I assume given a C# class:
public class CSharpClass{
public string? Prop1 {get; init;}
public string? Prop2 {get; init;}
}
it's using the existing F# init properties syntax
let test = CSharpClass(Prop1="Test", Prop2="Test2")
However, I tested in .net 5.0 preview 7 and the F# compiler has no errors, but builds an "Invalid Program" according to the CLR.
Also with the simpler case of initializing inside a constructor.
type TestFsharp() as this=
inherit CSharpClass ()
do
this.Prop1 <- "Yo"
this.Prop2 <- "What"
Also
Unhandled exception. System.InvalidProgramException: Common Language Runtime detected an invalid program.
at Program.TestFsharp..ctor()
at Program.main(String[] argv)
If you try to mutate an init only property outside an initialization block, it also compiles without error, but throws a runtime error. So at the very least that should be a compiler error, and thus am sure .net 5.0 preview 7 F# does not do anything yet for init only properties.
I thought I would take the time to make suggestions for the interop story with 3 cases of init only properties from C#.
So the General Case is a random C# class with an init only setter.
public class CSharpClass{
public string? Prop1 {get; init;}
public string? Prop2 {get; init;}
}
Probably handed by the previously mentioned CSharpClass(Prop1="Test", Prop2="Test2") and should work from constructor too.
Then there are 2 C# Record cases. Luckily not allowing inheritance of these records from F# seems like a legit path and would simplify things.
The most attractive C# Record types for developers are the positional records with a primary constructor.
public record CSharpRecord(string Prop1, string Prop2);
With these you may not even need to to use the init only properties in F# because you could use F# Record syntax {Prop1="Test; Prop2="Test2"} and it would be very similar to how you initialize F# records, and Copy them. {source with Prop1="Test1"}
However C# Records don't need to have a primary constructor.
// with empty constructor
public record CSharpRecord {
public string? Prop1 {get; init;}
public string? Prop2 {get; init;}
}
//rando constructor
public record CSharpRecord {
public CSharpRecord(bool rando){
Prop1 = rando.ToString();
}
public string? Prop1 {get; init;}
public string? Prop2 {get; init;}
}
And then I suppose you'd be left with the general case CSharpRecord(Prop1="Test", Prop2="Test2"), or if there was an empty constructor you could might be able to use the Record syntax safely if you can identify it as a C# Record. And with any record, if you can identify it, it should still possible to syntactically supporting copy {source with Prop1="Test1"} but you'd have to use the <Clone>$ method and init only properties the way C# does. It may be preferred to do this for Positional Records with Primary Constructors, I'm not sure.
Pros and Cons
The advantages of making this adjustment to F# are compiling functioning programs when consuming a C# type with init only properties!
The disadvantages of making this adjustment to F# is its needed for .net 5.0 which is coming up fast! At the very least needs compiler errors.
Extra information
Estimated cost (XS, S, M, L, XL, XXL): ?????
Links:
C# 9.0 init only Proposal (mentions F# would be changed):
https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/init.md
C# 9.0 Records Proposal:
https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/records.md
Related Suggestions:
#903
Affidavit (please submit!)
Please tick this by placing a cross in the box:
Please tick all that apply:
For Readers
If you would like to see this issue implemented, please click the 👍 emoji on this issue. These counts are used to generally order the suggestions by engagement.
I'm not sure what the current interop plan for F# is with init only properties in general is?
I assume given a C# class:
it's using the existing F# init properties syntax
However, I tested in .net 5.0 preview 7 and the F# compiler has no errors, but builds an "Invalid Program" according to the CLR.
Also with the simpler case of initializing inside a constructor.
Also
If you try to mutate an init only property outside an initialization block, it also compiles without error, but throws a runtime error. So at the very least that should be a compiler error, and thus am sure .net 5.0 preview 7 F# does not do anything yet for init only properties.
I thought I would take the time to make suggestions for the interop story with 3 cases of init only properties from C#.
So the General Case is a random C# class with an init only setter.
Probably handed by the previously mentioned
CSharpClass(Prop1="Test", Prop2="Test2")and should work from constructor too.Then there are 2 C# Record cases. Luckily not allowing inheritance of these records from F# seems like a legit path and would simplify things.
The most attractive C# Record types for developers are the positional records with a primary constructor.
With these you may not even need to to use the init only properties in F# because you could use F# Record syntax
{Prop1="Test; Prop2="Test2"}and it would be very similar to how you initialize F# records, and Copy them.{source with Prop1="Test1"}However C# Records don't need to have a primary constructor.
And then I suppose you'd be left with the general case
CSharpRecord(Prop1="Test", Prop2="Test2"), or if there was an empty constructor you could might be able to use the Record syntax safely if you can identify it as a C# Record. And with any record, if you can identify it, it should still possible to syntactically supporting copy{source with Prop1="Test1"}but you'd have to use the<Clone>$method and init only properties the way C# does. It may be preferred to do this for Positional Records with Primary Constructors, I'm not sure.Pros and Cons
The advantages of making this adjustment to F# are compiling functioning programs when consuming a C# type with init only properties!
The disadvantages of making this adjustment to F# is its needed for .net 5.0 which is coming up fast! At the very least needs compiler errors.
Extra information
Estimated cost (XS, S, M, L, XL, XXL): ?????
Links:
C# 9.0 init only Proposal (mentions F# would be changed):
https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/init.md
C# 9.0 Records Proposal:
https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/records.md
Related Suggestions:
#903
Affidavit (please submit!)
Please tick this by placing a cross in the box:
Please tick all that apply:
For Readers
If you would like to see this issue implemented, please click the 👍 emoji on this issue. These counts are used to generally order the suggestions by engagement.