C#でも分数class

前の記事で、C++で分数classを作ったのですが（https://qiita.com/HitsujiRere/items/43a4b53c64b8eec3b7bd ）、C#でも書いてみようと思ったので書きました


前記事（C++編）の参考
- http://blog.livedoor.jp/add20/archives/2285655.html 
- http://www002.upp.so-net.ne.jp/ys_oota/effec/chapter4.htm

コードは下記（# コード）

# 内容
コメントを書き忘れたのですが、C++の記事とほぼ同じですし、大体はコードを読んでもらえるとわかると思います

※**numerは分子**、**denomは分母**を表しています

あと、ToString()や四則演算，等号不等号，キャストを実装してありますので、使い物にはなると思います

# 感想
C++やC#、どちらも良いところがあるなと感じた

C++ではlong→Fractionのキャストを書かなくても、インスタンスから自動的に変換してくれる（みたいだ

C#ではメソッドなどがかなり書きやすいと感じた（慣れもあるかもしれない

# コード
コードはこちら
VS19で書いたのでnamespaceがありますが、そこを適当に変えるor削除するなどお願います

```c#
using System;

namespace Fraction_cs
{
    class Fraction
    {
        public long numer { get; private set; }
        public long denom { get; private set; }

        public Fraction(long numer = 0)
        {
            this.numer = numer;
            this.denom = 1;
        }
        public Fraction(long numer, long denom)
        {
            this.numer = numer;
            this.denom = denom;
            Normal();
        }
        public Fraction(Fraction b)
        {
            this.numer = b.numer;
            this.denom = b.denom;
        }

        static void Swap<T>(ref T a, ref T b)
        {
            var tmp = a;
            a = b;
            b = tmp;
        }
        static long GCD(long a, long b)
        {
            a = Math.Abs(a);
            b = Math.Abs(b);

            if (a < b) Swap(ref a, ref b);

            if (a == 1) return b;

            var tmp = a;
            while (b != 0)
            {
                tmp = b;
                b = a % b;
                a = tmp;
            }

            return tmp;
        }
        static long LCM(long a, long b)
        {
            a = Math.Abs(a);
            b = Math.Abs(b);
            if (a > b) Swap(ref a, ref b);

            if (a == 1) return b;

            var tmp = a;
            while (tmp % b != 0)
            {
                tmp += a;
            }
            return tmp;
        }
        void Normal()
        {
            var gcd = GCD(numer, denom);

            numer /= gcd;
            denom /= gcd;

            if (denom < 0)
            {
                numer *= -1;
                denom *= -1;
            }
        }

        public override string ToString()
        {
            if (denom == 1)
            {
                return numer.ToString();
            }
            else
            {
                return numer + "/" + denom;
            }
        }
        public override bool Equals(object b)
        {
            if (b is Fraction b2 &&
                this.numer == b2.numer &&
                this.denom == b2.denom)
            {
                return true;
            }

            return false;
        }
        public static long Compare(Fraction a, Fraction b)
        {
            var lcm = LCM(a.denom, b.denom);

            return (lcm / a.denom) * a.numer - (lcm / b.denom) * b.numer;
        }

        public static bool operator ==(Fraction a, Fraction b)
        {
            return a.Equals(b);
        }
        public static bool operator !=(Fraction a, Fraction b)
        {
            return !a.Equals(b);
        }
        public static bool operator >=(Fraction a, Fraction b)
        {
            return Compare(a, b) >= 0;
        }
        public static bool operator >(Fraction a, Fraction b)
        {
            return Compare(a, b) > 0;
        }
        public static bool operator <=(Fraction a, Fraction b)
        {
            return Compare(a, b) <= 0;
        }
        public static bool operator <(Fraction a, Fraction b)
        {
            return Compare(a, b) < 0;
        }

        public static Fraction operator +(Fraction a, Fraction b)
        {
            var lcm = LCM(a.denom, b.denom);
            var numer = a.numer * (lcm / a.denom) + b.numer * (lcm / b.denom);

            return new Fraction(numer, lcm);
        }
        public static Fraction operator -(Fraction a, Fraction b)
        {
            var lcm = LCM(a.denom, b.denom);
            var numer = a.numer * (lcm / a.denom) - b.numer * (lcm / b.denom);

            return new Fraction(numer, lcm);
        }
        public static Fraction operator *(Fraction a, Fraction b)
        {
            var gcd = GCD(a.numer, b.denom);
            var numer = a.numer / gcd;
            var denom = b.denom / gcd;

            gcd = GCD(b.numer, a.denom);
            numer *= b.numer / gcd;
            denom *= a.denom / gcd;

            return new Fraction(numer, denom);
        }
        public static Fraction operator /(Fraction a, Fraction b)
        {
            var gcd = GCD(a.numer, b.numer);
            var numer = a.numer / gcd;
            var denom = b.numer / gcd;

            gcd = GCD(b.denom, a.denom);
            numer *= b.denom / gcd;
            denom *= a.denom / gcd;

            return new Fraction(numer, denom);
        }

        public static Fraction operator +(Fraction a)
        {
            return new Fraction(a);
        }
        public static Fraction operator -(Fraction a)
        {
            var b = new Fraction(a);
            b.numer *= -1;
            return b;
        }

        public static Fraction operator ++(Fraction a)
        {
            a.numer++;
            a.Normal();
            return new Fraction(a);
        }
        public static Fraction operator --(Fraction a)
        {
            a.numer--;
            a.Normal();
            return new Fraction(a);
        }

        public static implicit operator Fraction(long a)
        {
            return new Fraction(a);
        }
        public static explicit operator double(Fraction a)
        {
            return (double)a.numer / (double)a.denom;
        }
    }
}
```