Closed ufcpp closed 3 years ago
45:34~ FirstOrNull
からの、where
違い拡張メソッドオーバーロード
#nullable enable
using System.Collections.Generic;
_ = new[] { 1 }.FirstOrNull();
_ = new[] { "" }.FirstOrNull();
static class EnumerableClass
{
public static T? FirstOrNull<T>(this IEnumerable<T> source) where T : class => null;
// ここにあるとダメ。 .NET の型システム的に where 違いのオーバーロード無理。
//public static T? FirstOrNull<T>(this IEnumerable<T> source) where T : struct => null;
}
static class EnumerableStruct
{
// 別の型にあるなら OK。
public static T? FirstOrNull<T>(this IEnumerable<T> source) where T : struct => null;
}
↑ どうせ↓みたいな分岐ができなくてつむことが多々ある。
1:00:32~ 引数なしコンストラクターがないことで ImmutableArray の類が困ってる
// 書きたいコード
//struct FixedArray4
//{
// int[] _array = new int[4];
// public int this[int index] => _array[index];
//}
// しょうがないから書くコード
struct FixedArray4
{
int[] _array;
private FixedArray4(int[] array) => _array = array;
// これがいやーーーーー
public static FixedArray4 Create() => new(new int[4]);
public int this[int index] => _array[index];
}
1:03:18~ new()
が default
扱いされるせいでぬるぽ回避が極めて難しい
using System;
using System.Collections.Immutable;
// 構造体の引数なしコンストラクターがないというか、
//ImmutableArray<int> array = default;
// 今、 new() が default 扱いされてしまい…
ImmutableArray<int> array = new();
// IndexOutOfRange ほしいのに、ぬるぽが来る
// 何を new したんでしょう…
Console.WriteLine(array[0]);
// この判定が必要
Console.WriteLine(array.IsDefault);
1:08:35~ 引数なしコンストラクターは C# 6.0 のときに一度やろうとして、Activator.CreateInstance のバグを踏んだことで取りやめになった
using System;
// C# 6.0 の頃、これが構造体コンストラクターを呼んでくれないというバグあった。
var point = Activator.CreateInstance<Point>();
struct Point
{
public int[] _data;
// .NET のメタデータ的には昔から許されてた。
// C# コンパイラーをちょこっといじれば可能だったらしい。
public Point() => _data = new int[1];
}
1:14:59~ (今持っていない状態でリリース済みの)既存の構造体に引数なしコンストラクターを足すのは破壊的変更になります
引数なしコンストラクターを足した瞬間にコンパイルできなくなるコードの例:
void m(Point p = new())
{
}
struct Point
{
// この行の有無だけで m がエラーになるかどうか変わる。
// つまり、引数なしコンストラクターの追加は破壊的変更。
public Point() { }
}
using System;
void m(Point p = new()) // warning waves で警告くらいは出すべきかも
{
}
struct Point
{
}
1:28:12~ 今現在、 where T : struct
は必ず where T : new()
を満たす扱いを受けてる
今後、↑この前提は必ずしも正しくなくなる。 ただ、コンパイル時にエラーにはできなくて、実行時例外が出る状態になるかも。
using System;
m2<Point>();
// 今、「struct の時点で new() を満たす」という判定を受けてる。
void m1<T>() where T : new()
{
// new T() は中で Activator.CreateInstance<T>() を呼んでる
Console.WriteLine(new T());
}
// 今、これ許される。
// さすがに変えれない。
void m2<T>() where T : struct => m1<T>();
struct Point
{
// これを足すと破壊。
// new T() のところで MissingMethodException が出る。
private Point() { }
}
1:37:00~ .NET って「0バイト構造体」が実はなかったりする(現時点では)
using System;
unsafe
{
Console.WriteLine(sizeof(Empty)); // これ1
}
struct Empty { }
1:39:44 にしてやっとサムネ回収。
var var = new var();
class var { }
@record record = new record();
record record { }
1:41:18~ Visual Studio 上だといいけども…
Roslyn みたいにsemantics見まくってるものと同水準のシンタックスハイライト、普通は期待できない。 実際、GitHub 上のハイライトはちょっと変。
1:44:10~ semantics 見なくてもいい文法になればちょっと GitHub とかブログサービスとかに優しくなれる
// これ、破壊的変更するかも。
// 今後、semantics 見なくても「var はここで出てきたらキーワード」扱いしたい
var var = new var();
// record はそうだから。
// そして C# 9.0 がリリースされて、それで困った人もいない。
record record = new record();
// @ を付ければいいじゃない。
//@record record = new record();
class var { }
record record { }
2:16:55~ global using の扱いは「すべてのファイルの先頭にその using をべた展開するのと同じ扱い」になる
2:17:13~「通常 using よりも上」みたいな新しいスコープは導入しない
global using System;
using System;
// これ OK
using D = System.DateTime;
// これダメ
// global using でもダメということにするらしい。
// global using はべたに「すべてのファイルの先頭にその using を展開」扱い。
using D1 = DateTime;
;
namespace A
{
// これは OK
using D = DateTime;
}
2:06:18 sharplab 仕事はえぇ (global using の feature ブランチをもう試せる)
using System;
var x = 1;
// エイプリルフールその1、オタマジャクシ演算子
Console.WriteLine(~-x);
Console.WriteLine(-~x);
「 60進数リテラル」「エイプリルフール」
41:55~ SignalR に nullable アノテーション付いたらしい → 制約なし T?
とか MemberNotNull
がないとやっぱきついよねみたいな話
1:46:43~ class は(文脈抜きで)単純にキーワードなので C# だと @
必須
からの、「他の言語で klass
とか clazz
とかよく見た」話。
1:48:10 「cls とか略すと clear screen? ってなる」「C# script には #cls
ディレクティブで実際 clear screen する文法がある」
1:50:50~ 「もういっそ ß 使えば?ドイツ語のエスツェット。s 2つの合字。 claß」
(ちなみに、Microsoft IME だと「ss」って打って変換で ß が出る)
1:51:46~ 文字コードさえ覚えれいれば何の文字でも F5 キーで入力可能 それが後々「なんとかしてくれるゼロ幅スペース」の話に。
2:24:57 「global using 使いたいと思わない」とかいうけど、ソースコード新規追加したときのデフォルトの using
うざいじゃない
特に System.Text
。単独で使いたいのは StringBuilder
しかいない。
(Encoding
とかはだいたい System.IO
とセット。)
(Regex
は System.Text.RegularExpressions
名前空間。)
実際、「StringBuilder
は System
名前空間にあるべきだった」って言われてる(中の人が反省してるの見たことある)。
(StringInfo
とか UnicodeCategory
とかは System.Globalization
名前空間だし。)
今(.NET 5 以降)は System.Text.Rune
があるけども。
配信枠: https://youtu.be/NqJkCm85CSM
.NET 6 Preview 2 になってる。
前回残ったやつ:
そこからブログ1記事増えたやつ:
https://github.com/ufcpp-live/UfcppLiveAgenda/issues/27 も未消化多い。