Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C# 9.0 ほぼ確定 #14

Closed
ufcpp opened this issue Sep 5, 2020 · 7 comments
Closed

C# 9.0 ほぼ確定 #14

ufcpp opened this issue Sep 5, 2020 · 7 comments

Comments

@ufcpp
Copy link
Collaborator

ufcpp commented Sep 5, 2020

https://github.com/dotnet/roslyn/pull/47483/files?short_path=62d2c4c#diff-62d2c4ce577204aa80f67774438c2beb
https://github.com/dotnet/csharplang/pull/3850/files?short_path=589e171#diff-589e171052e5ee92c87a797075782193

9.0 から漏れたもの、Language Feature Status の「9.0」テーブルから「Next」テーブルに移動された。
「9.0」テーブルに並んでるものは全部 merge 済み。
Language Version History も更新。

前回の配信で言ったように、record がらみにはもうちょっと修正が入ることは確定しているものの、それ以外についてはこれで C# 9.0 の内容が確定と思われる。

一方で、前回、気づいてなかった merge 済み機能が2つほど:

みんクラの後に「2回行動」配信やろうかな。

@ufcpp
Copy link
Collaborator Author

ufcpp commented Sep 5, 2020

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;

Console.WriteLine(RuntimeFeature.CovariantReturnsOfClasses);

foreach (var i in (1, 2))
{
    Console.WriteLine(i);
}

class Base
{
    public virtual object M() => new object();
}

class Derived : Base
{
    public override string M() => "";
}

static class TupleExtensions
{
    public struct Tuple2Enumerator<T> : IEnumerator<T>
    {
        private int _i;
        private (T, T) _tuple;

        public Tuple2Enumerator((T, T) tuple)
        {
            _i = 0;
            _tuple = tuple;
        }

        public T Current => _i switch
        {
            1 => _tuple.Item1,
            2 => _tuple.Item2,
            _ => default!,
        };

        public bool MoveNext() => ++_i < 3;

        object IEnumerator.Current => Current!;
        void IDisposable.Dispose() { }
        void IEnumerator.Reset() => throw new NotImplementedException();
    }

    public static Tuple2Enumerator<T> GetEnumerator<T>(this (T, T) t) => new(t);
}

@ufcpp-live
Copy link
Owner

今日のかき捨てコード1
covariant returns、一番の用途は Clone かな

class Base
{
    public virtual Base Clone() => new Base();
}

class Derived : Base
{
    public override Derived Clone() => new Derived();
}

@ufcpp-live
Copy link
Owner

2
2-tuple に拡張メソッド書いてても、3-tuple には対応できない。
C# には variadic template がないので…

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;

foreach (var i in (1, 2, 3))
{
    Console.WriteLine(i);
}

static class RangeExtensions
{
    public static IEnumerable<int> GetEnumerator(this Range r)
    {
        for (int i = r.Start.Value; i < r.End.Value; i++)
        {
            yield return i;
        }
    }
}


static class TupleExtensions
{
    public struct Tuple2Enumerator<T> : IEnumerator<T>
    {
        private int _i;
        private (T, T) _tuple;

        public Tuple2Enumerator((T, T) tuple)
        {
            _i = 0;
            _tuple = tuple;
        }

        public T Current => _i switch
        {
            1 => _tuple.Item1,
            2 => _tuple.Item2,
            _ => default!,
        };

        public bool MoveNext() => ++_i < 3;

        object IEnumerator.Current => Current!;
        void IDisposable.Dispose() { }
        void IEnumerator.Reset() => throw new NotImplementedException();
    }

    public static Tuple2Enumerator<T> GetEnumerator<T>(this (T, T) t) => new(t);

    public struct Tuple3Enumerator<T> : IEnumerator<T>
    {
        private int _i;
        private (T, T, T) _tuple;

        public Tuple3Enumerator((T, T, T) tuple)
        {
            _i = 0;
            _tuple = tuple;
        }

        public T Current => _i switch
        {
            1 => _tuple.Item1,
            2 => _tuple.Item2,
            3 => _tuple.Item3,
            _ => default!,
        };

        public bool MoveNext() => ++_i < 4;

        object IEnumerator.Current => Current!;
        void IDisposable.Dispose() { }
        void IEnumerator.Reset() => throw new NotImplementedException();
    }

    public static Tuple3Enumerator<T> GetEnumerator<T>(this (T, T, T) t) => new(t);
}

@ufcpp-live
Copy link
Owner

質問: 以下のコードが NRT 警告出ないのはどういう状況か?

// 問題あり。
// 問題として認識はされてる。
// 「いつ修正される」までは保証なし。
new string[] { null, "w,w" }.Where(x => x != null).Select(x => x.Split(","));

@ufcpp-live
Copy link
Owner

  • Pubternal??
    • private protected が入ったときにキーワード何にするかで相当悩んでたの思い出した
      • proternal, protected_and_internal, ...
  • System.Half
    • Intrinsics で対応しだしてからが本番で、今のところソフトウェア実装しかないので遅い
    • 機械学習方面では「半精度」で十分、かつ、データ転送量の方がネックになるので half が欲しいことが

@ufcpp-live
Copy link
Owner

かき捨てコード3
Extension GetEnumerator は Range に対しても使えはするんだけど…
public/標準ライブラリに入れるには怖い実装にしかならない。internal な分には便利。

using System;
using System.Collections.Generic;

//for (int i = 1; i < 5; i++) { }foreach (var i in 1..5) // 1, 2, 3, 4
{
    Console.WriteLine(i);
}

foreach (var i in 1..) // 無限シーケンス。 break 必須
{
    Console.WriteLine(i);
}

foreach (var i in 1..^3) // ダメだろ
{
    Console.WriteLine(i);
}

internal static class RangeExtensions
{
    public static IEnumerator<int> GetEnumerator(this Range r)
    {
        if (r.Start.IsFromEnd) throw new InvalidOperationException();
        if (r.End.IsFromEnd)
        {
            if(r.End.Value == 0)
            {
                for (int i = 0; ; i++)
                {
                    yield return i;
                }
            }
            throw new InvalidOperationException();
        }

        for (int i = r.Start.Value; i < r.End.Value; i++)
        {
            yield return i;
        }
    }
}

@ufcpp-live
Copy link
Owner

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants