Skip to content

Instantly share code, notes, and snippets.

@ufcpp
Created June 17, 2024 07:56
Show Gist options
  • Save ufcpp/f7ff31329a6d51ce8ad0ad87825027fa to your computer and use it in GitHub Desktop.
Save ufcpp/f7ff31329a6d51ce8ad0ad87825027fa to your computer and use it in GitHub Desktop.
構造体の Dispose いつ見てもつらみ
var a = new A();
var b = new B();
var c = new C();
// using 越し、defensive copy されたインスタンスで Dispose 呼ばれるので、元の a, b は書き変わらない。
using (a) using (b) using (c) { }
Console.WriteLine(a.X); // false
Console.WriteLine(b.X); // false
// インターフェイスへのキャストして呼ぶのもダメ。
// box 化起きてて、box インスタンスの方が書き変わって、元の a は書き変わらない。
((IDisposable)a).Dispose();
Console.WriteLine(a.X); // false
// 直呼びなら書き変わる。
// (明示的実装はしづらい)
a.Dispose();
b.Dispose();
Console.WriteLine(a.X); // true
Console.WriteLine(b.X); // true
// ジェネリックメソッドに ref T で渡すなら書き変わる。
static void M<T>(ref T x) where T : IDisposable => x.Dispose();
M(ref c);
Console.WriteLine(c.X); // true
struct A : IDisposable
{
public bool X { get; private set; }
public void Dispose() => X = true;
}
ref struct B
{
public bool X { get; private set; }
public void Dispose() => X = true;
}
struct C : IDisposable
{
public bool X { get; private set; }
void IDisposable.Dispose() => X = true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment