滅入るんるん

何か書きます

Kotlin使いのためのC#入門 Compare of Kotlin 1.1

> Top

Coroutine

Kotlin1.1で実験的な機能として追加されたCoroutineですが、KotlinのCoroutine自体C#とGoのmix inな形のようで非常に複雑になっていますが、C#の場合は単純です。

というのも、KotlinのCoroutineはCoroutineという機能にスレッド移動を加え非同期処理もできるようになっています。

C#ではCoroutineと非同期処理は別になっており、Coroutineはyield・非同期処理はasync/awaitとなっています。

class Coroutine
{
    // IEnumerableはKotlinで言うところのSequenseのようなもの
    public IEnumerable<int> Range(int start, int end)
    {
        for (int i = start; i <= end; i++)
        {
            yield return i;
        }
    }

    public void Main()
    {
        foreach (int i in Range(10, 20))
        {

        }
    }
}

class AsyncAwait
{
    // TaskはKotlinで言うところのDeferredのようなもの
    public async Task<int> DelayReturn(int value)
    {
        await Task.Delay(1000);
        return value;
    }

    public async Task Main()
    {
        int result = await DelayReturn(10);
    }
}

Type aliases

Type aliasesに似た機能として、C#にはusing aliasがありますが、どちらかというとimport asに似ているので割愛

関数に名前を付けるというのであれば、C#のdelegateというのが似ていますが、もはやあまり使われない機能です。C#ではおとなしくラムダや、メソッド参照しましょう。

Bound callable references

::オペレーターでメンバーの参照を採れるようになりましたが、C#ではメソッドをフィールドのようにアクセスすることによってメソッドの参照を取れます。

class MethodRef
{
    public int Add(int a, int b)
    {
        return a + b;
    }

    public void Main()
    {
        Func<int, int, int> add = Add;
        // thisなのでどちらの書き方でもいい
        add = this.Add;
        int result = add(1, 2);
    }
}

お気づきかもしれませんが、C#ではフィールドのようにアクセスしていようが、その定義はフィールドやプロパティとは限りません。メソッドであることもあります。 このようにメソッドもオブジェクトとして見ることを第一級オブジェクトとか言うようです。(第一級関数とかいう言葉もありますが、違いなんてよくわからないので、正確なことはググって調べてみてください)

Sealed and data classes

C#にはSealed classがないので割愛。 data classに関してはそのうち似た機能が追加されそうです

Destructuring in lambdas

タプルとかユーザー定義型の分解とかはありますが、ラムダの引数ではできない(たぶん)ので割愛。

Underscores for unused parameters

class UnUsed
{
    public (int,int) Sub()
    {
        return (1, 2);
    }

    public void Main()
    {
        // ラムダの引数では_は変数扱い
        Action<int, int> action = (_, i) => Console.WriteLine(_);
        var (_, j) = Sub();
        Console.WriteLine(j);
        Console.WriteLine(_); // コンパイルエラー:_という変数はない
    }
}

アンダースコアによる破棄はいろいろと機能があるので、詳しくはドキュメントを参照してください。

Underscores in numeric literals

class SeparateNumber
{
    private readonly int n10000 = 1_0000;
    private readonly int hex = 0x_FF_FF;
}

C# 7.xで順次機能追加されました。

Shorter syntax for properties

Kotlinの記法の糖衣構文なので省略したいところですが、いちおう似た書き方はあります。

class Property
{
    // こっちはフィールド、=か=>かで変わる
    public readonly string Text = "";

    // getを式風に省略したプロパティ
    public int Value => 1;

    // 初期値は自動実装プロパティのみ付けれる
    public int Default { get; } = 0;
}

getを式風に書くとフィールドとの見分けがつきにくくなるので、個人的にはあまりお勧めしませんが、いちおう似た書き方はあります。

Inline property accessors

C#にはinline化を確実にさせる機能がないので割愛。

Local delegated properties

C#にはdelegated propertiesがないので割愛。

Interception of delegated property binding

C#にはdelegated propertiesがないので割愛。

Generic enum value access

C#とKotlinのenumは構造が違っていて、C#では構造体の1種であるため、同列扱いできないため割愛。


これ以降標準ライブラリ的な話だったので割愛。