Created
May 23, 2023 21:33
-
-
Save hsytkm/3d74415a9267d2fb0a9834b4d6a9fc9f to your computer and use it in GitHub Desktop.
C# Owner Belongings
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace ConsoleApp1; | |
public interface IBelonging<T> | |
where T : IBelonging<T> | |
{ | |
static abstract Owner<T> Create(); | |
} | |
public readonly record struct Owner<T> : IDisposable | |
where T : IBelonging<T> | |
{ | |
private readonly T _value; | |
private readonly Action<T>? _release; | |
public bool IsNone => _release is null; | |
public T Value | |
{ | |
get | |
{ | |
if (IsNone) throw new InvalidOperationException(); | |
return _value; | |
} | |
} | |
public Owner(T value, Action<T> release) | |
{ | |
_value = value ?? throw new ArgumentNullException(nameof(value)); | |
_release = release ?? throw new ArgumentNullException(nameof(release)); | |
} | |
public void Dispose() => _release?.Invoke(_value); | |
} | |
public sealed class MyObject : IBelonging<MyObject> | |
{ | |
private MyObject() { } | |
~MyObject() => _release(this); | |
private static readonly Action<MyObject> _release = static self => | |
{ | |
Console.WriteLine("Disposed MyObject"); | |
}; | |
public static Owner<MyObject> Create() => new(new MyObject(), _release); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// [(C#) オブジェクトの破棄の可否を型で制限する - ネコのために鐘は鳴る](https://ikorin2.hatenablog.jp/entry/2023/02/13/072121) | |
using ConsoleApp1; | |
Owner<MyObject> obj = MyObject.Create(); | |
UseObject1(obj.Value); | |
UseObject2(obj); | |
void UseObject1(MyObject obj) | |
{ | |
// MyObject を使う。 | |
// 破棄出来ない (== 破棄しなくてよい) | |
} | |
void UseObject2(Owner<MyObject> obj) | |
{ | |
// MyObject を使う。 | |
// ここで破棄する (== 破棄する責任があることが型で明示されている) | |
obj.Dispose(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment