英文:
F# library that subclasses a class from a C# library
问题
不需要代码,只翻译文本部分:
I want to convert the C# classes in my console app to F#, one at a time. With stunning help from Co-pilot, I got one class done. But I can’t build with it. So I made a tiny test solution, to investigate. I’m using .NET 7.0 SDK (v7.0.201)
The C# compiler complains:
- Program.cs(7, 14): [CS0712] Cannot create an instance of the static class 'Class2'
- Program.cs(7, 1): [CS0723] Cannot declare a variable of static type 'Class2'
- Program.cs(8, 29): [CS1061] 'Class2' does not contain a definition for 'Greeting' and no accessible extension method 'Greeting' accepting a first argument of type 'Class2' could be found (are you missing a using directive or an assembly reference?)
- Program.cs(8, 49): [CS1061] 'Class2' does not contain a definition for 'Number' and no accessible extension method 'Number' accepting a first argument of type 'Class2' could be found (are you missing a using directive or an assembly reference?)
I’m just learning how to write a class in F#, and I can’t see how to fix this.
英文:
I want to convert the C# classes in my console app to F#, one at a time. With stunning help from Co-pilot, I got one class done. But I can’t build with it. So I made a tiny test solution, to investigate. I’m using
.NET 7.0 SDK (v7.0.201)
The C# compiler complains:
- Program.cs(7, 14): [CS0712] Cannot create an instance of the static class 'Class2'
- Program.cs(7, 1): [CS0723] Cannot declare a variable of static type 'Class2'
- Program.cs(8, 29): [CS1061] 'Class2' does not contain a definition for 'Greeting' and no accessible extension method 'Greeting' accepting a first argument of type 'Class2' could be found (are you missing a using directive or an assembly reference?)
- Program.cs(8, 49): [CS1061] 'Class2' does not contain a definition for 'Number' and no accessible extension method 'Number' accepting a first argument of type 'Class2' could be found (are you missing a using directive or an assembly reference?)
I’m just learning how to write a class in F#, and I can’t see how to fix this.
#!/bin/bash
dotnet new sln
dotnet new console -o Console
dotnet new classlib -o LibraryC
dotnet new classlib -lang "F#" -o LibraryF
dotnet sln add Console/Console.csproj
dotnet sln add LibraryC/LibraryC.csproj
dotnet sln add LibraryF/LibraryF.fsproj
dotnet add LibraryF reference LibraryC
dotnet add Console reference LibraryF
cat << 'EOT' > LibraryC/Class1.cs
namespace LibraryC;
public class Class1 {
public virtual int Number => 17;
public virtual string Greeting() => "Hello";
}
EOT
cat << 'EOT' > LibraryF/Library.fs
namespace LibraryF
open LibraryC
module Class2 = // ANSWER: Remove this.
type Class2() =
inherit Class1()
member this.Junk() = "not static"
override this.Number = 42
override this.Greeting() =
let fromBase = base.Greeting()
$"{fromBase} from Class2 {this.Number}"
EOT
cat << 'EOT' > Console/Program.cs
using LibraryC;
using LibraryF;
var class1 = new Class1();
Console.WriteLine($"{class1.Greeting()} {class1.Number}");
var class2 = new Class2();
Console.WriteLine($"{class2.Greeting()} {class2.Number}");
EOT
(Wouldn’t it be nice if you could say dotnet dump
and get a shell file like this?)
答案1
得分: 4
如在评论中提到的,您在LibraryF
内声明了一个模块Class2
,而仅在此模块内有一个类Class2
。F#模块被编译为静态类,所以如果您打开LibraryF
,Class2
指的是表示该模块的静态类。
您可以通过从F#库中删除模块声明来解决这个问题(只有在您还想要拥有顶层let
绑定(如函数或全局值)时,才需要模块,但如果您不需要这些,可以直接将类放在一个命名空间内):
英文:
As mentioned in the comments, you are declaring a module Class2
inside LibraryF
and only inside this module, you have a class Class2
. F# modules are compiled as static classes and so if you open LibraryF
, the Class2
refers to the static class representing the module.
You can resolve this by dropping the module declaration from the F# library (you would only need a module if you also wanted to have top-level let bindings such as functions or global values, but if you do not need those, you can put the class directly inside a namespace):
namespace LibraryF
open LibraryC
type Class2() =
inherit Class1()
member this.Junk() = "not static"
override this.Number = 42
override this.Greeting() =
let fromBase = base.Greeting()
$"{fromBase} from Class2 {this.Number}"
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论