Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions csharp/Platform.Disposables.Tests/DisposableTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,108 @@ private static string GetDisposalObjectTestProjectFilePath()
}
return path;
}

[Fact]
public static void WrapSystemIDisposableInDisposableTest()
{
var disposed = false;
var testDisposable = new TestDisposable(() => disposed = true);

// Test creating wrapper from System.IDisposable using Create method
var wrapper = Disposable.Create(testDisposable);
Assert.NotNull(wrapper);
Assert.False(disposed);

wrapper.Dispose();
Assert.True(disposed);
}

[Fact]
public static void WrapSystemIDisposableInGenericDisposableTest()
{
var disposed = false;
var testDisposable = new TestDisposable(() => disposed = true);

// Test creating generic wrapper from System.IDisposable using Create method
var wrapper = Disposable<System.IDisposable>.Create(testDisposable);
Assert.NotNull(wrapper);
Assert.Same(testDisposable, wrapper.Object);
Assert.False(disposed);

wrapper.Dispose();
Assert.True(disposed);
}

[Fact]
public static void WrapTwoSystemIDisposableInDisposableTest()
{
var disposed1 = false;
var disposed2 = false;
var testDisposable1 = new TestDisposable(() => disposed1 = true);
var testDisposable2 = new TestDisposable(() => disposed2 = true);

// Test creating wrapper for two System.IDisposable objects using Create method
var wrapper = Disposable<System.IDisposable, System.IDisposable>.Create((testDisposable1, testDisposable2));
Assert.NotNull(wrapper);
Assert.Same(testDisposable1, wrapper.Object);
Assert.Same(testDisposable2, wrapper.AuxiliaryObject);
Assert.False(disposed1);
Assert.False(disposed2);

wrapper.Dispose();
Assert.True(disposed1);
Assert.True(disposed2);
}

[Fact]
public static void AsDisposableExtensionMethodTest()
{
var disposed = false;
var testDisposable = new TestDisposable(() => disposed = true);

// Test extension method that wraps System.IDisposable in Disposable
var wrapper = testDisposable.AsDisposable();
Assert.NotNull(wrapper);
Assert.False(disposed);

wrapper.Dispose();
Assert.True(disposed);
}

[Fact]
public static void AsDisposableContainerExtensionMethodTest()
{
var disposed = false;
var testDisposable = new TestDisposable(() => disposed = true);

// Test extension method that wraps System.IDisposable in Disposable<System.IDisposable>
var wrapper = testDisposable.AsDisposableContainer();
Assert.NotNull(wrapper);
Assert.Same(testDisposable, wrapper.Object);
Assert.False(disposed);

wrapper.Dispose();
Assert.True(disposed);
}

private class TestDisposable : System.IDisposable
{
private readonly Action _disposeAction;
private bool _disposed = false;

public TestDisposable(Action disposeAction)
{
_disposeAction = disposeAction ?? throw new ArgumentNullException(nameof(disposeAction));
}

public void Dispose()
{
if (!_disposed)
{
_disposed = true;
_disposeAction();
}
}
}
}
}
8 changes: 8 additions & 0 deletions csharp/Platform.Disposables/Disposable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ public Disposable(Action action)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Disposable(Disposal disposal) => new Disposable(disposal);

/// <summary>
/// <para>Creates a new <see cref="Disposable"/> object that wraps the specified <see cref="System.IDisposable"/> object.</para>
/// <para>Создает новый объект <see cref="Disposable"/>, который оборачивает указанный объект <see cref="System.IDisposable"/>.</para>
/// </summary>
/// <param name="disposable"><para>The <see cref="System.IDisposable"/> object to wrap.</para><para>Объект <see cref="System.IDisposable"/> для оборачивания.</para></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Disposable Create(System.IDisposable disposable) => new Disposable(() => disposable?.Dispose());

/// <summary>
/// <para>Disposes unmanaged resources.</para>
/// <para>Высвобождает неуправляемые ресурсы.</para>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@ public Disposable(TPrimary @object) : base(@object) { }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Disposable<TPrimary, TAuxiliary>(ValueTuple<TPrimary, TAuxiliary> tuple) => new Disposable<TPrimary, TAuxiliary>(tuple.Item1, tuple.Item2);

/// <summary>
/// <para>Creates a new <see cref="Disposable{TPrimary, TAuxiliary}"/> object that wraps two <see cref="System.IDisposable"/> objects and calls their Dispose methods when disposed.</para>
/// <para>Создает новый объект <see cref="Disposable{TPrimary, TAuxiliary}"/>, который оборачивает два объекта <see cref="System.IDisposable"/> и вызывает их методы Dispose при высвобождении.</para>
/// </summary>
/// <param name="disposables"><para>The tuple containing two <see cref="System.IDisposable"/> objects to wrap.</para><para>Кортеж, содержащий два объекта <see cref="System.IDisposable"/> для оборачивания.</para></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Disposable<System.IDisposable, System.IDisposable> Create(ValueTuple<System.IDisposable, System.IDisposable> disposables) => new Disposable<System.IDisposable, System.IDisposable>(disposables.Item1, disposables.Item2, (obj1, obj2) => { obj1?.Dispose(); obj2?.Dispose(); });

/// <summary>
/// <para>Creates a new copy of the primary object (<see cref="Disposable{TPrimary}.Object"/>).</para>
/// <para>Создаёт новую копию основного объекта (<see cref="Disposable{TPrimary}.Object"/>).</para>
Expand Down
8 changes: 8 additions & 0 deletions csharp/Platform.Disposables/Disposable[T].cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ public Disposable(T @object, Action<T> action)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Disposable<T>(T @object) => new Disposable<T>(@object);

/// <summary>
/// <para>Creates a new <see cref="Disposable{T}"/> object that wraps the specified <see cref="System.IDisposable"/> object and calls its Dispose method when disposed.</para>
/// <para>Создает новый объект <see cref="Disposable{T}"/>, который оборачивает указанный объект <see cref="System.IDisposable"/> и вызывает его метод Dispose при высвобождении.</para>
/// </summary>
/// <param name="disposable"><para>The <see cref="System.IDisposable"/> object to wrap.</para><para>Объект <see cref="System.IDisposable"/> для оборачивания.</para></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static new Disposable<System.IDisposable> Create(System.IDisposable disposable) => new Disposable<System.IDisposable>(disposable, obj => obj?.Dispose());

/// <summary>
/// <para>Creates a new copy of the primary object (<see cref="Disposable{T}.Object"/>).</para>
/// <para>Создаёт новую копию основного объекта (<see cref="Disposable{T}.Object"/>).</para>
Expand Down
18 changes: 18 additions & 0 deletions csharp/Platform.Disposables/IDisposableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,23 @@ public static void DisposeIfNotDisposed(this IDisposable disposable)
disposable.Dispose();
}
}

/// <summary>
/// <para>Wraps a <see cref="System.IDisposable"/> object in a <see cref="Disposable"/> wrapper.</para>
/// <para>Оборачивает объект <see cref="System.IDisposable"/> в обёртку <see cref="Disposable"/>.</para>
/// </summary>
/// <param name="disposable"><para>The <see cref="System.IDisposable"/> object to wrap.</para><para>Объект <see cref="System.IDisposable"/> для оборачивания.</para></param>
/// <returns><para>A new <see cref="Disposable"/> wrapper.</para><para>Новая обёртка <see cref="Disposable"/>.</para></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Disposable AsDisposable(this System.IDisposable disposable) => Disposable.Create(disposable);

/// <summary>
/// <para>Wraps a <see cref="System.IDisposable"/> object in a <see cref="Disposable{T}"/> wrapper.</para>
/// <para>Оборачивает объект <see cref="System.IDisposable"/> в обёртку <see cref="Disposable{T}"/>.</para>
/// </summary>
/// <param name="disposable"><para>The <see cref="System.IDisposable"/> object to wrap.</para><para>Объект <see cref="System.IDisposable"/> для оборачивания.</para></param>
/// <returns><para>A new <see cref="Disposable{T}"/> wrapper.</para><para>Новая обёртка <see cref="Disposable{T}"/>.</para></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Disposable<System.IDisposable> AsDisposableContainer(this System.IDisposable disposable) => Disposable<System.IDisposable>.Create(disposable);
}
}
Loading