Closed ufcpp closed 1 year ago
1.M();
file static class X
{
public static void M(this int _) => Console.WriteLine("Program.cs");
}
https://gist.github.com/ufcpp/0a9928ad0343f4cb0218e055d7d50d0b
TypedReference 戻り値まだダメらしい。
TypedReference m() => default;
API diff:
var data = new byte[] { 99, 100, 97, 98, 101 };
//data.Min(); data.MinBy();
foreach (var x in data.Order()) // OrderBy(x => x)
{
Console.WriteLine(x);
}
C# クラス名に使えないファイル名うけるwwww
ちなみに、🍎🍏🍖🍣
空文字列 .cs と、ZWJ.cs
普通のスペースは Windows に怒られた。
inner class ダメだった。
partial 併用はいけた
file partial class A
{
}
partial class FileLocal // これ、見た目は internal なものの、file 扱い受けてそう。
{
public void M() => MInFilePartial();
}
file partial class FileLocal
{
public void MInFilePartial() { }
}
int x = 1;
int y = 1;
int z = 1;
var (r1, r2) = M(ref x, ref y, ref z);
r1.Reference = 2;
r2.Reference = 3;
Console.WriteLine((x, y, z)); // 2, 3, 1
#if 本当に書きたかったもの
(ref int, ref int) M(ref int a, ref int b, ref int c)
{
// 何かしら分岐するとして
return (ref a, ref b);
}
// ValueTuple<ref int, ref int> があればいいんだけども…
// 要望としては出てるけども、ちょっと実装するとなると大変かも。
#endif
// ref 多値戻り値
RefTuple<int, int> M(ref int a, ref int b, ref int c)
{
// 何かしら分岐するとして
return new(ref a, ref b);
}
ref struct RefTuple<T1, T2>
{
public ref T1 Item1;
public ref T2 Item2;
public RefTuple(ref T1 item1, ref T2 item2)
{
Item1 = ref item1;
Item2 = ref item2;
}
#if false
// これは書けるけど、やりたいことじゃない。
public void Deconstruct(out T1 item1, out T2 item2)
{
item1 = Item1;
item2 = Item2;
}
// 本当にやりたいことはこれだけど、無理。
// すなわち、ref tuple deconstruct 無理。
public void Deconstruct(out ref T1 item1, out ref T2 item2)
{
item1 = ref Item1;
item2 = ref Item2;
}
#endif
// ref deconstruct やろうとすると、
// ByReference<T> みたいなの介する必要あり。
public void Deconstruct(out ByReference<T1> item1, out ByReference<T2> item2)
{
item1 = new(ref Item1);
item2 = new(ref Item2);
}
}
ref struct ByReference<T>
{
public ref T Reference;
public ByReference(ref T reference) => Reference = ref reference;
}
using System.Runtime.InteropServices;
ref struct X
{
public int A;
// これ、現状はダメ。
//[UnscopedRef] // RC1 で多分入る
//public ref int M() => ref A;
// ところがこれはOK。
// MemoryMarshal の時点で unsafe。
// 使い方間違うとマジで escape analysis ミスって死ぬ。
public ref int M()
=> ref MemoryMarshal.CreateSpan(ref A, 1)[0];
}
static A n(scoped ref int x)
{
x = 123;
return new A();
}
static A nUnsafe(scoped ref int x)
{
return new A
{
// 嘘つき。
// scoped って言ってるのに、x を外に漏らす。
// まあ、Unsafe ですんで…
X = ref System.Runtime.CompilerServices.Unsafe.AsRef(x)
};
}
// コンパイラー チーム的には「やるべきかも」と思ってるけど、
// C# ユーザー的には管理しきれる気がしない書き方(案)。
[return: LifeTime(nameof(a))]
ref int ma(ref int a, ref int b)
{
b = 1;
return ref a;
}
[return: LifeTime(nameof(b))]
ref int mb(ref int a, ref int b)
{
a = 1;
return ref b;
}
// 仮想的に提案されてる life time annotation 文法:
ref<A> int ma(ref<A> int a, ref<B> int b) => ref a;
ref<B> int mb(ref<A> int a, ref<B> int b) => ref b;
さすがによくわからない… (ufcpp.net 内に function pointer の解説はいまだにありません!)
TypedReference の話からの、「使い道のない/使われてないキーワードランキング」の話に。
int x = 1;
//TypedReference.Create(ref x); これがあれば __makeref 要らなくできる。
TypedReference r = __makeref(x);
__refvalue(r, int) = 2;
Console.WriteLine(__reftype(r));
Console.WriteLine(x);
class A
{
[property: My] // [My] と全く同じ意味になるから property: 要らないよね
public int X { get; set; }
}
record R(
[My] // 引数に対する指定に
[property: My] // property が要らない子じゃなくなった!
int X);
class X<[typevar: My] T> { } // これこそ [My] と全く一緒
class MyAttribute : Attribute { }
//TypedReference m() => default;
配信URL: https://youtu.be/EoNDVaynqMk
.NET 7 Preview 6 のときは配信さぼったわけで、ほぼ2か月ぶり。 (p6 のときに、ref fields が一応入ってたものの、escape analysis が未実装だったのでちょっとスルー。)
C# 11