C# 到 F# 类转换

发布于 2024-12-12 00:56:24 字数 3744 浏览 0 评论 0原文

我很久以前就是一名 C# 开发人员。

我学习 F# 并将其用于科学目的/研究/认可工作。我发现它的许多功能都很强大,但我在编写类方面遇到了困难——这是我知道在 C# 中做得很好的基本内容。

对我(和社区)有帮助的是翻译以下 C# 代码。

class CoolAttribute : Attribute
{
}

class BaseClass
{
    public BaseClass(int zzz)
    {
        // zzz doesn't matter; what matters is that zzz is required
    }

    public virtual void XHello()
    {
        Console.WriteLine("I'm BaseClass.");
    }
}

interface IFirst
{
    void Hello();
}

interface ISecond
{
    int MagicNumber();
}

[DebuggerDisplay("pubI = {pubI}")]
class SampleClass : BaseClass, IFirst, ISecond
{
    private int privI;
    protected int protI;
    public int pubI;

    private static string s_privStr;

    static SampleClass()
    {
        s_privStr = "";
    }

    public event Action<string> OnSomething = (el) => { };

    public int PubI
    {
        get { return pubI; }
        set { pubI = value; }
    }

    public static string StatStr
    {
        get { return s_privStr; }
    }

    // Default constructor
    SampleClass()
        : base(0)
    {
        privI = 1;
        protI = 2;
        pubI = 3;
    }

    // Other constructor
    SampleClass(int a, int b, int c)
        : base(a + b + c)
    {
        privI = a;
        protI = b;
        pubI = c;
    }

    [Conditional("DEBUG")]
    public void PubSimpleMethod()
    {
    }

    protected virtual void ProtVirtMethod()
    {
        OnSomething("From the virt method.");
    }

    private static void PrivStatMethod()
    {
    }

    public void Hello()
    {
        Console.WriteLine("Hello (IFirst)");
    }

    public override void XHello()
    {
        Console.WriteLine("I'm SampleClass");
    }

    public int MagicNumber()
    {
        return privI + protI + pubI;
    }

    public void Additional([Cool] int i)
    {
    }

    public static SampleClass operator +(SampleClass a, SampleClass b)
    {
        return new SampleClass(a.privI + b.privI,
            a.protI + b.protI,
            a.pubI + b.pubI);
    }
}

F# 翻译 [正在进行中,将更新答案]:

//// wrong ...
//type CoolAtribute =
//    extend Attribute

type BaseClass(zzz : int) =
    // virtual
    abstract XHello : unit -> unit
    default this.XHello() = 
        printfn "I'm BaseClass."

// seems Ok
type IFirst =
    abstract Hello : unit

type ISecond = 
    abstract MagicNumber : int

[<DebuggerDisplay("pubI = {pubI}")>] // ????
type SampleClass() =
    inherit BaseClass(0) // necessary argument ? 1 constructor
    // implements IFirst, ISecond

    let mutable privI = 0 // initialization required
    // protI
    // pubI

    // wrong:
    //let static mutable s_privStr = ""

    // static constructor

    // event OnSomething

    // seems Ok
    member this.PubI
        with get() = privI
        and  set(value) = privI <- value

    // ??
    //static member StatStr
    //    with get() = s_privStr
    //    and  set(value) = s_privStr <- value


    // Default constructor


    // Other constructor
    // C#: SampleClass(int a, int b, int c)

    [<Conditional("DEBUG")>]
    member this.PubSimpleMethod() =
        do ignore

    abstract ProtVirtMethod : unit -> unit
    //protected 
    default this.ProtVirtMethod() =
        // raise event OnSomething("From the virt method.");

    //private
    //static
    member this.PrivStatMethod() =
        do ignore

    member this.Hello() =
        printfn "Hello (IFirst)"

    // override 
    member this.XHello() =
        printfn "I'm SampleClass"

    member this.MagicNumber() : int =
        privI + protI + pubI

    // apply attribute to the argument
    member this.Additional( (*[Cool*) i :int) =
        do ignore

    // operator +

I'm a C# dev since long ago.

I learn F# and use it for scientific purposes/research/approbation works. I find many its functional features powerful but I'm straggling to write classes — the essential thing I know to do very well in C#.

What would help me (and the community) is to translate the following C# code.

class CoolAttribute : Attribute
{
}

class BaseClass
{
    public BaseClass(int zzz)
    {
        // zzz doesn't matter; what matters is that zzz is required
    }

    public virtual void XHello()
    {
        Console.WriteLine("I'm BaseClass.");
    }
}

interface IFirst
{
    void Hello();
}

interface ISecond
{
    int MagicNumber();
}

[DebuggerDisplay("pubI = {pubI}")]
class SampleClass : BaseClass, IFirst, ISecond
{
    private int privI;
    protected int protI;
    public int pubI;

    private static string s_privStr;

    static SampleClass()
    {
        s_privStr = "";
    }

    public event Action<string> OnSomething = (el) => { };

    public int PubI
    {
        get { return pubI; }
        set { pubI = value; }
    }

    public static string StatStr
    {
        get { return s_privStr; }
    }

    // Default constructor
    SampleClass()
        : base(0)
    {
        privI = 1;
        protI = 2;
        pubI = 3;
    }

    // Other constructor
    SampleClass(int a, int b, int c)
        : base(a + b + c)
    {
        privI = a;
        protI = b;
        pubI = c;
    }

    [Conditional("DEBUG")]
    public void PubSimpleMethod()
    {
    }

    protected virtual void ProtVirtMethod()
    {
        OnSomething("From the virt method.");
    }

    private static void PrivStatMethod()
    {
    }

    public void Hello()
    {
        Console.WriteLine("Hello (IFirst)");
    }

    public override void XHello()
    {
        Console.WriteLine("I'm SampleClass");
    }

    public int MagicNumber()
    {
        return privI + protI + pubI;
    }

    public void Additional([Cool] int i)
    {
    }

    public static SampleClass operator +(SampleClass a, SampleClass b)
    {
        return new SampleClass(a.privI + b.privI,
            a.protI + b.protI,
            a.pubI + b.pubI);
    }
}

F# translation [work in progress, to be updated with answers]:

//// wrong ...
//type CoolAtribute =
//    extend Attribute

type BaseClass(zzz : int) =
    // virtual
    abstract XHello : unit -> unit
    default this.XHello() = 
        printfn "I'm BaseClass."

// seems Ok
type IFirst =
    abstract Hello : unit

type ISecond = 
    abstract MagicNumber : int

[<DebuggerDisplay("pubI = {pubI}")>] // ????
type SampleClass() =
    inherit BaseClass(0) // necessary argument ? 1 constructor
    // implements IFirst, ISecond

    let mutable privI = 0 // initialization required
    // protI
    // pubI

    // wrong:
    //let static mutable s_privStr = ""

    // static constructor

    // event OnSomething

    // seems Ok
    member this.PubI
        with get() = privI
        and  set(value) = privI <- value

    // ??
    //static member StatStr
    //    with get() = s_privStr
    //    and  set(value) = s_privStr <- value


    // Default constructor


    // Other constructor
    // C#: SampleClass(int a, int b, int c)

    [<Conditional("DEBUG")>]
    member this.PubSimpleMethod() =
        do ignore

    abstract ProtVirtMethod : unit -> unit
    //protected 
    default this.ProtVirtMethod() =
        // raise event OnSomething("From the virt method.");

    //private
    //static
    member this.PrivStatMethod() =
        do ignore

    member this.Hello() =
        printfn "Hello (IFirst)"

    // override 
    member this.XHello() =
        printfn "I'm SampleClass"

    member this.MagicNumber() : int =
        privI + protI + pubI

    // apply attribute to the argument
    member this.Additional( (*[Cool*) i :int) =
        do ignore

    // operator +

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

山人契 2024-12-19 00:56:24

大多数代码对我来说看起来不错,但是您不能使用普通的 member 来定义虚拟方法。 (这是因为 F# 代码通常不使用实现继承,因此并不经常需要)。

要定义虚拟方法,需要使用abstractdefault

type Virtual() = 
  abstract Foo : int -> int
  default this.Foo(n) = n + 1

要重写派生类型中的方法,可以编写:

type Derived() =
  inherit Virtual()

  override this.Foo(n) = n + 2    

Most of the code looks good to me, but you can't use plain member to define virtual methods. (This is because F# code does not typically use implementation inheritance, so this is not needed that often).

To define a virtual method, you need to use abstract and default:

type Virtual() = 
  abstract Foo : int -> int
  default this.Foo(n) = n + 1

To override the method in a derived type, you can write:

type Derived() =
  inherit Virtual()

  override this.Foo(n) = n + 2    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文