Переход с класса C # на F # - PullRequest
1 голос
/ 26 октября 2011

Я давно являюсь разработчиком 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 +

1 Ответ

5 голосов
/ 26 октября 2011

Большая часть кода выглядит хорошо для меня, но вы не можете использовать простой member для определения виртуальных методов.(Это потому, что код F # обычно не использует наследование реализации, поэтому это не требуется часто).

Чтобы определить виртуальный метод, вам нужно использовать abstract и default:

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

Чтобы переопределить метод в производном типе, вы можете написать:

type Derived() =
  inherit Virtual()

  override this.Foo(n) = n + 2    
...