Closed ufcpp closed 1 year ago
[UnscopedRef]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _x0, 4);
[UnscopedRef]
public ref T this[int index] => ref AsSpan()[index];
//ref Unsafe.Add(ref _x0, index);
// これエラー
static Ref m1(scoped ref int i) => new Ref(ref i);
static Ref m2(scoped ref int i)
{
return new(ref i);
}
// => 形式、かつ、target-typed new の時に限り、フロー解析漏れる。
static Ref m3(scoped ref int i) => new(ref i);
ref struct Ref
{
public ref int Item1;
public Ref(ref int item1) => Item1 = ref item1;
}
↑ 17.5 マイルストーンで直すって。 = .NET 7 GA のタイミングではまだバグったまま出すらしい。
using System.Collections.Immutable;
var array = new[] { 1, 2, 3, };
var x = array[0];
var y = array?[0]; // null-conditional []
// flag ? [1] : [2] はどっち?
// flag?[1] が優先されて、 null-conditional [] か?
// flag ? : が優先されて、conditional [1] or [2] か?
bool flag = true;
List<List<int>> list = [flag ? [1] : [2]];
// dictionary literal、現状の最有力候補文法
Dictionary<int, string> map = [1: "", 2: ""];
// ここで改めて、[flag ? [1] : [2]] を見る
// flag?[1] キー、[2] 値のディクショナリ
// flag で分岐した [1] or [2] 値のリスト
// 以下の2個、通ってもおかしくない。
Dictionary<int, List<int>> d = [flag?[1] : [2]];
List<List<int>> l = [flag ? [1] : [2]];
// [flag ? [1] : [2]]みたいな問題、まあ、C# 1.0 の頃からあるんで…
var x = 1;
var y = 2;
var z = x+++y;
var z1 = x+ ++y;
var z2 = x++ +y;
var z3 = x + + +y;
var z3_ = x + (+(+y));
var w = x++ + ++y;
var w1 = x+++++y; // エラー
Action a = () => { };
a.Invoke(); // 書かないよね。
a?.Invoke(); // これ必須なん?
a?(); // 書きたい…?!かも…
// ↓が不明瞭なので a?() ができない。
flag ? (1 + 2) : (3 + 4);
// さっきの、スペースの有無で ?: と ?[] を切り替えるのはいれば、
// ?() も行けるはず。
// ↓も!?
flag ? .1 : .2;
// 有効なC#コード。
var x = .1_1e1_1;
let 󠄀 = "E0100"
let 󠄁 = "E0101"
print(󠄀 + 󠄁)
let 𝟎 = 1;
let 𝟘 = 2;
let 𝟢 = 3;
let 𝟬 = 4;
let 𝟶 = 5;
print(𝟎 + 𝟘 + 𝟢 + 𝟬 + 𝟶)
string? x = "1";
// var y = x!.Length; これを
var y = x!
.Length; // こうすることあるよね
// じゃあこれは?
var z = x?
.Length;
// ? の後ろのスペースの有無で意味変わる未来ワンチャンある。
var w1 = x ? .X : .Y;
var w2 = x?.X;
var e1 = x switch
{
[] => TooLongLongEnumName.X,
[_] => TooLongLongEnumName.X | TooLongLongEnumName.Y,
[_, _] => TooLongLongEnumName.Y,
};
//提案: target-type スコープ推論
TooLongLongEnumName e1 = x switch
{
[] => .X,
[_] => .X | .Y,
[_, _] => .Y,
};
[Flags]
enum TooLongLongEnumName { X=1, Y=2 }
Base x = new Base.A();
Base y = new .A(); // さっきの enum の .X と同じ理屈
// discriminated union もどき
public class Base
{
private Base() { }
public class A : Base { }
public class B : Base { }
}
// C# 11 からの新人はクラス名に使うと警告どころじゃなく、エラーになりました。
using System.Reflection;
class file { }
class scoped { }
class async { }
class await { }
class record { }
class X
{
int field;
public int P
{
get
{
return field; // class file をエラーにできるんならワンチャンこれも!!!
}
}
}
.NET 7 RC2
.NET 7 も RC2 に。
が、まあ、RC 1 のとき同様、この時期に新機能とか入るはずもなく。
次もう GA (.NET Conf の 11/8 辺り)なはず。
ref がらみ
ちょっとだけ治ってた: https://twitter.com/ufcpp/status/1580019722917011456
一部のバグ、17.5 マイルストーン行きしてる。
vNext な話題
LDM 10/10
C# Language Design Meeting for October 10th, 2022
x?.X = value;
→ 前向き追記: 追加で Notes 2件:
field キーワード
時間的な都合で11から外れただけなので割とすぐに実装されそうなものの…
csharplang/issues/6530
「field をキーワード扱いするか、普通の識別子(明示的なフィールド、ローカル変数等)扱いするか」で、あんまり頑張ると循環依存がすぐに発生して困るとか。 シンプルに判定したく、「無条件にキーワード扱いするか、少なくともセマンティクス見なくていい範囲でやりたい」みたいな話。
→ 思ったより大変みたい。
(field: 0)
とかnew { field = 0 }
とかif (x is { field: _ })
とか。non-record primari constructors
既存の primary constructors 提案は「レコードとともに完了」扱いにして、別途 Primary constructors in non-record classes and structs 提案ドキュメントを追加。
レコードみたいに引数から public プロパティは作らない。参照があれば private フィールドにして、なければフィールドすら作らない。Deconstruct メソッドの生成もしない。
Collection literals
早速ワーキンググループの議事録が
これまで出てる提案の概要まとめとか。 あと、dictionary リテラルの方の話も。
[ "key": value ]
みたいな文法になるかも。?:
との弁別どうしようか問題。[ x?[i] : [j] ]
が2通りの解釈。x?[i]
キーの dictionaryx
が true のとき list[i]
、 false のとき list[j]
?
と[
の間にスペースがあるかどうかで意味を分岐させた方がいいかもみたいな話もあり。