Skip to content

Instantly share code, notes, and snippets.

View ufcpp's full-sized avatar

Nobuyuki Iwanaga ufcpp

View GitHub Profile
@ufcpp
ufcpp / ConstraintOverload.cs
Created April 16, 2025 12:06
OverloadResolutionPriority を使った制約違いオーバーロード(多引数)
using System.Runtime.CompilerServices;
// where が多いほど優先度を上げておかないと ambiguous エラー起こす。
// where の数が同じものは優先度も同じで大丈夫。
Console.WriteLine("* A");
A.M<C1, C1>();
A.M<C2, C1>();
A.M<C1, C2>();
A.M<C2, C2>();
@ufcpp
ufcpp / StructClass.cs
Last active April 18, 2025 01:35
OverloadResolutionPriority を使った制約違いオーバーロード
using System.Runtime.CompilerServices;
Ex.M<C1>(); // where class
Ex.M<S1>(); // where struct
Ex.M<C2>(); // where class, I
Ex.M<S2>(); // where struct, I
Ex.M<I>(); // これは class, I に行く。インターフェイスは参照型なので。
static void M1<T>() => Ex.M<T>(); // none
using System.Buffers;
using System.Diagnostics;
using System.Runtime.CompilerServices;
/// <summary>
/// とりあえず Add する一方の Dictionary 的な実装。
/// ちゃんと「増えすぎたら古いのから消す」みたいな処理入れるなら自前でやるのちょっとつらく、
/// Ben.StringIntern とかの導入考えた方がよさげ。
/// </summary>
class InternPool
@ufcpp
ufcpp / JsonSourceGeneration.cs
Created March 10, 2025 07:44
System.Text.Json.Serialization の Source Generator、そういう仕様なんだ…
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
IJsonTypeInfoResolver r = new SourceGenerationContext();
Console.WriteLine(r.GetTypeInfo(typeof((One, TwoThree)), new()) is null); // not null
Console.WriteLine(r.GetTypeInfo(typeof((OneTwo, Three)), new()) is null); // null
// タプルのとき、 source generator が作るメソッドの名前は Create_Value{T1}{T2} らしく…
[JsonSourceGenerationOptions(WriteIndented = true)]
@ufcpp
ufcpp / BitFlags.cs
Created February 26, 2025 14:24
Nullable<T> のコスト高すぎると思うの
using System.Runtime.CompilerServices;
#if false
M(new A { X = 1 });
M(new B { X = 1 });
M(new A { Y = 2 });
M(new B { Y = 2 });
M(new A { X = 1, Y = 2 });
M(new B { X = 1, Y = 2 });
M(new A { });
@ufcpp
ufcpp / ThisAndRefThis.cs
Created February 13, 2025 07:53
OverloadResolutionPriority でそういうことはできないっぽい
using System.Runtime.CompilerServices;
int x = 1;
_ = x.M(); // 拡張メソッドの this 引数は ref 渡しできる。
_ = (x * x).M(); // ref 渡しには右辺値は渡せないので M(ref int) を呼べない。
// M(int) の方呼んでほしいけどもダメっぽい。エラーに。
static class A
{
@ufcpp
ufcpp / Sum.cs
Created December 13, 2024 01:54
CS9236 with the Sum extension method overloads.
using System.Runtime.CompilerServices;
using static Enumerable;
int[][] x = [[]];
var y = x.Sum(x => x.Sum(x => 1));
#if false
// Same as System.Linq.Enumerable, this causes CS9236.
static class Enumerable
@ufcpp
ufcpp / ToHexString.cs
Last active December 11, 2024 12:48
byte 列の16進ダンプ文字列化
using BenchmarkDotNet.Attributes;
using System.Runtime.CompilerServices;
using System.Text;
using C = System.Globalization.CultureInfo;
#if DEBUG
var data = ToHexStringBenchmark.StaticData;
var s = data.A1();
Console.WriteLine(data.A1() == s);
@ufcpp
ufcpp / Gen.cs
Created November 14, 2024 14:00
Interceptors こんなのなら割と実用的かなぁ
namespace ConsoleApp1
{
using System.Runtime.CompilerServices;
file class Gen
{
[InterceptsLocation(@"F:\src\ConsoleApp1\ConsoleApp1\Program.cs", 1, 16)]
public static ReadOnlySpan<byte> M1(string _) => [1, 2, 3, 10, 11, 12, 100, 200, 255];
[InterceptsLocation(@"F:\src\ConsoleApp1\ConsoleApp1\Program.cs", 2, 16)]
public static ReadOnlySpan<byte> M2(string _) => [0x83, 0x01, 0x01, 0x02, 0xC3, 0x61, 0x62, 0x63, 0x03, 0xA2, 0xFF, 0x00];
@ufcpp
ufcpp / FloorMaxValue.cs
Created November 13, 2024 10:16
(int)Math.Floor(float.MaxValue) の挙動違うらしい…
// (int)Math.Floor(float.MaxValue) は、
// .NET 8 だとなぜか int.MinValue
// .NET 9 だと int.MaxValue になってそう。
// .NET 9 でだけ永久ループ…
M((int)Math.Floor(float.MaxValue), (int)Math.Floor(float.MaxValue));
Console.WriteLine("done.");
static void M(int x, int y)