ufcpp-live / UfcppLiveAgenda

@ufcpp live streaming agenda
MIT License
24 stars 2 forks source link

C# 13 候補紹介 #87

Closed ufcpp closed 4 months ago

ufcpp commented 7 months ago

配信 URL: https://www.youtube.com/watch?v=8Vls-qrx-F8

https://github.com/ufcpp-live/UfcppLiveAgenda/issues/85 を取り上げる感じで C# 13 (or later) 候補話を。

半分くらいはいきたい。

ufcpp-live commented 7 months ago
var array = new int[] { 1, 2, 3 };
C.M(array); // Calls the array overload
C.M([1, 2, 3]); // Calls the span overload

array.Enumerate(); // IE だと拡張メソッド呼べるのに

array.Extension(); // Span だと拡張メソッド呼べない

static class C
{
    public static void M(int[] _) { }
    public static void M(ReadOnlySpan<int> _) { }

    public static void Extension(this ReadOnlySpan<int> _) { }
    public static void Enumerate(this IEnumerable<int> _) { }
}
ufcpp-live commented 7 months ago
using (new C()) { }
using (new S()) { }
using (new RS()) { } // OK

static async ValueTask T()
{
    // 余談
    await using (new C()) { } // 後入りの await using はインターフェイス不要
}

class C : IDisposable // クラスの場合は必須
{
    public void Dispose() { }
    public ValueTask DisposeAsync() => default;
}

struct S : IDisposable // 普通の構造体の場合は必須
{
    public void Dispose() { }
}

ref struct RS // : IDisposable ← ref struct は無理
{
    public void Dispose() { }
}
ufcpp-live commented 7 months ago
M<RS>();

static void M<T>(T x)
    where T : IMyInterface, allows ref struct
{
    x.M();

    object obj = x; // boxing。ダメ!絶対!
    IMyInterface local = x; // これも box。ダメ。
}

interface IMyInterface
{
    void M();
}

ref struct RS : IMyInterface
{
    public void M()
    {
        throw new NotImplementedException();
    }
}
ufcpp-live commented 7 months ago
1.M(); // C2 と C3 で不明瞭かも
(Span<int>[1]).M(); // 許される?

static class C2
{
    public static void M<T>(this T _) where T : struct { }
}

static class C3
{
    public static void M<T>(this T _) where T : struct, allows ref struct { }
}
ufcpp-live commented 7 months ago
C.M<int>(); // T? は int?
C.M<int?>(); // T? は int??… あっ… ダメ…

// where T がなかったとして
C.M<string?>(); // T? は string?? じゃなくて string?。これはこれで謎

// 他の言語だと Optional<Optional<T>> 認めてたりするのでだいぶ事情が違う。

static class C
{
    public static T? M<T>()
        where T : struct
        => null;

    public static T? M<T>() // 代わりに T? と掛けちゃダメという制限あってもいい
        where T : struct, allows nullable // これほしい
        => null;
}
ufcpp-live commented 7 months ago
    public static void M<T>()
        where T : struct
        // ↓こんなの挟まってたら嫌だし…
        //where T1 : class
        //where T2 : class
        //where T3 : class
        //where T4 : class
        //where T5 : class
        //where T6 : class
        //where T7 : class
        //where T8 : class
        // 初期案。2行に分けたくなくて没。
        allows T : ref struct
        { }
ufcpp-live commented 7 months ago

image

ufcpp-live commented 7 months ago
// パラメーターであるのなら
var len = args.Length; // OK
var name = nameof(args); // OK

class args { } // OK (パラメーター名での shadowing OK)

class C
{
    public void M(args args) { } // shadowing の例。
}

// まあ、こいつは Program.Main から自動変換したとき、
// args がパラメーターのままの方が都合がいい。
ufcpp-live commented 7 months ago
internal class Program
{
    private static void Main(string[] hoge) // args をリネーム
    {
        // Covnert to top-level statements がそもそも出てこなくなった
    }
}
ufcpp-live commented 7 months ago

image

ufcpp-live commented 7 months ago

image

ufcpp-live commented 7 months ago
class C
{
    public string X
    {
        get => "";
        set
        {
            // C# 13 で、field だけキーワードにした場合
            var n1 = nameof(value);
            var n2 = nameof(field); // これだけエラー?きもい…

            // もし value がキーワードになったらこれがまずいかも。
            if (value is null)
                throw new ArgumentNullException(nameof(value));

            // これなら平気。
            ArgumentNullException.ThrowIfNull(value);
        }
    }
}
ufcpp-live commented 7 months ago

エラーそっちなんかい。 image

ufcpp-live commented 7 months ago

image

ufcpp-live commented 7 months ago

image

ufcpp-live commented 7 months ago

image

ufcpp-live commented 7 months ago
// あいう は、SJIS だと6バイト
// UTF-16 だと6バイト
// UTF-8 だと9バイト
Console.WriteLine("あいう", int.Parse("")); // Parse の位置の interceptor location、文字コードによって変わる
ufcpp-live commented 7 months ago

バグ報告案件:

using System.Runtime.CompilerServices;

MyArray x = default;
Span<int> xspan = x;
Span<int> xsplat = [.. xspan];

Console.WriteLine(xspan.Length);
Console.WriteLine(xsplat.Length);

Span<int> maybeBug = [.. x];

Console.WriteLine(maybeBug.Length); // 0

[InlineArray(4)]
struct MyArray
{
    private int _value;
}
ufcpp commented 4 months ago

↑のバグ報告案件は roslyn 70708 で既知だった。 「ニッチシナリオだから優先度低め」扱い受けてる。 フィードバック次第で考えるって。