Closed ufcpp closed 1 year ago
// .NET Fx 1 のころからこう。今更何も変わらず。
//var x = double.NaN;
//var y = double.NaN;
//Console.WriteLine(x == y);
//Console.WriteLine(x.Equals(y));
var v1 = new System.Numerics.Vector3(0, 0, float.NaN);
var v2 = new System.Numerics.Vector3(0, 0, float.NaN);
Console.WriteLine(v1 == v2); // false
Console.WriteLine(v1.Equals(v2)); // これが .NET 6→7 で false→true
// たぶん、float → Vector<float> 使った vectorize 最適化とかしてる人だけが踏む地雷。
「みんな、.NET 7 にすぐ上げる?」的な話題の中で:
var x = """
raw string だけ書ければ文句ない。
LangVersion 11 で十分。
TargetFramework 変えるモチベーションはそこまでない。
""";
/*
* これをコピペすると
{ "aaa": "bbb" }
*/
var x = """
{ "aaa": "bbb" }
""";
// 最近のアプデで Visual Studio 自動成型してくれる
var y = "{ \"aaa\": \"bbb\" }\n";
var z = @"{ ""aaa"": ""bbb"" }
";
// lang=json //,strict
var x = """
{
1: 1,
true: false,
abc: "abc", // aaa
}
""";
// lang=json
var x = """
{
"a": 1,
"b": 2, // この時点で A, B そろったので parse 打ち切る
"a": 3
}
""";
.NET Framewor 1.0 やで。
<TargetFramework>net10</TargetFramework>
var a = 1;
var b = 1;
var c = 1;
var d = 1;
// これ、今 OK
var x = (a<b, (c)>(d));
// intersection type (案)
// この手の文法、今後も足せない疑惑。
// () を使えない。
// () が出てくると、上記の (c) のところ壊す。
(IEnumerable<float> | IEnumerable<int>) m(){ }
unsafe
{
Console.WriteLine(sizeof(double?)); // 16になるのやだー!!
}
// Rust とかは、
// T が正常値として 0 を持たない保証があるとき、HasValue を消す
//struct Nullable<T>
//{
// public bool HasValue; // これが邪魔
// public T Value;
//}
//todo:
// 1. A みたいなラッパーの自動生成
// 2. 場合によっては A への変換を implicit に
M<A>(new(1));
M(1);
static void M<T>(T x)
where T : IMyInteface
{
Console.WriteLine(x.ToHexString());
}
public interface IMyInteface
{
string ToHexString();
}
// int に対して使いたいときは int のラッパーを1個作らないとダメ
public record struct A(int X) : IMyInteface
{
public string ToHexString() => X.ToString("X");
}
// 文法案
extension A of int : IMyInterface
// implicit extension A of int : IMyInterface
// role A of int : IMyInterface
{
}
var a = new A(0, 0);
serializer.Serialize(a);
// { "X": 0, "Y": 0 }
// 「デフォルト値だったら何も書かない」みたいなオプション指定で
// { } にしたい。
write<bool, Shape_bool>(false);
// role が入ると
// write(false); だけで行けるようになるはず。たぶん。
// さらに…
write<bool[], ArrayShape<bool, Shape_bool>>(false);
write<bool?, NullableShape<bool, Shape_bool>>(false);
write<bool?[], ArrayShape<NullableShape<bool, Shape_bool>>>(false);
// さらに…
// ArraySegment, Span, List, ImmutableArray
static void write<T, TShape>(T value)
where TShape : struct, Shape<T>
{
if (default(TShape).IsDefault(value))
{
// この時だけ書く
}
}
interface Shape<T>
{
bool IsDefault(T value);
}
struct Shape_bool : Shape<bool>
{
public bool IsDefault(bool value) => !value;
}
struct Shape_byte : Shape<byte>
{
public bool IsDefault(byte value) => value == 0;
}
struct Shape_int : Shape<int>
{
public bool IsDefault(int value) => value == 0;
}
// これを残り、sbyte, short, ushort, uint, long, ulong, float, double
// 場合によっては DateTime, DateTimeOffset, TimeSpan, Guid, TimeOnly, DateOnly, ...
// 最近だと Half, Int128, UInt128
特に static abstract も入ったので…
static void write<T, TShape>(T value)
// 元は
//where TShape : struct, Shape<T>
where TShape : Shape<T>
{
// 元は default(TShape).IsDefault
if (TShape.IsDefault(value))
{
// この時だけ書く
}
}
interface Shape<T>
{
// 元は bool IsDefault(T value);
static abstract bool IsDefault(T value);
}
m(new[] { 1, 2, 3 }, x => x < 2);
static int m(int[] data, Func<int, bool> pred)
{
var sum = 0;
foreach (var x in data)
{
if (predが前回と同じなら)
{
pred の中身をインライン展開
}
else if (pred(x)) sum += x;
}
return sum;
}
// 今の仕様だと内部で Array.CreateInstance(typeof(A), ...) 呼ぶ。
// これが AOT 環境で呼べない。
Enum.GetValues(typeof(A));
// 代わりに int[] で返せば AOT で動くよ!
// なぜなら、.NET では↓これが合法だから。
var array = (A[])(object)new int[] { 1, 2, 3 };
foreach (var x in array) Console.WriteLine(x);
enum A
{
X, Y, Z, W
}
サイズが同じな構造体は同じ扱い。
using System.Runtime.CompilerServices;
var data = new double[] { 1, 2, 3, -1 };
var asLong = Unsafe.As<double[], long[]>(ref data);
foreach (var x in asLong)
{
Console.WriteLine($"{x:X}");
}
// これに対して Unsafe.As<T[], Wrapper<T>[]>(ref array) はやる。
record struct Wrapper<T>(T Value);
今日のまとめは TL;DR: .NET 7 is fast.
// これ行ける
using System.Text;
const string s1 = $"aaa {nameof(Int32)} aaa";
// これ、Culture のせいで無理…
const string s2 = $"aaa {1.2} aaa";
// Culture 指定できたとしても、C# の言語使用が .NET ランタイムに依存するという問題がある。
// MM/dd/yyyy ゆするまじ。
// やーぽん絶許
// かつて、$"" 周りいろいろキモイことになってるので、
// $""u8 はほんとにそれが必要になるまで触れない方がいいと思う。
IFormattable u1 = $"";
A.m("");
A.m($"{1}");
StringBuilder sb = new();
sb.Append(""); // string
sb.Append($"{1}"); // AppendInterpolatedStringHandler
sb.Append($""); // string
class A
{
public static void m(string s) { }
public static void m(IFormattable s) { }
}
配信URL: https://youtu.be/EyrpKfC0q9k
feature triage
https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-08-24.md
去年に引き続き「これをもってC# 12に入る・入らないを占わないでほしい」という注釈付きで、11以後の話。 トリアージということになってるけど、内容的には「タスクの積み下ろし」程度。
こんな雰囲気だし、配信でも今積みタスク化してる提案振り返る?
ちなみに、その後、partial property は正式に提案 issue 立った。 csharplang/issues/6420
毎年恒例「Performance Improvements in .NET 7」
https://devblogs.microsoft.com/dotnet/performance_improvements_in_net_7/
つかめないスクロールバー。 導入文章にある「去年、長すぎると批判を受けた」。 「TL;DR: .NET 7 むっちゃ速い」。