Skip to content

Instantly share code, notes, and snippets.

@ufcpp
Last active February 9, 2018 05:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ufcpp/9e476a8a4bfaf04e3e1256bedfd83881 to your computer and use it in GitHub Desktop.
Save ufcpp/9e476a8a4bfaf04e3e1256bedfd83881 to your computer and use it in GitHub Desktop.
デリゲートの引数変換
using System;
// https://gist.github.com/AArnott/d285feef75c18f6ecd2b と同種の最適化、デリゲートの引数変換にも使えそうという話。
static class DelegateAdapter
{
// こっちだと、action をフィールドに持つクラスが1個作られて、
// var temp = new その匿名クラス();
// new Action(temp.Method);
// みたいなコードになる。
public static Action<int> ConvertSlow(Action<Alias> action) => x => action(new Alias(x));
// こっちだと、
// IntPtr p = DelegateAdapter.Adapt; // デリゲート生成じゃなくて、関数ポインターのロード(ldftn 命令)
// new Action(action, p);
// みたいなコードになる。
// 匿名クラスの new がない分お得。
// 拡張メソッドをデリゲート化するときにはこういう最適化が掛かってくれるらしい。
public static Action<int> ConvertFast(Action<Alias> action) => action.Adapt;
// なので、1段階拡張メソッドで包む。
public static void Adapt(this Action<Alias> action, int x) => action(new Alias(x));
}
// いわゆる strong typedef。中身 int なんだけど型で区別したい的なやつ。
public struct Alias
{
public int Value { get; }
public Alias(int value) => Value = value;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment