zig
zig

Reputation: 4624

Implementing a very basic IDisposable

I would like to implement a very simple IDisposable.
The whole idea is to measure the execution time of my methods which they all return a MethodResult. e.g.

public class MethodResult : IDisposable
{
    private Stopwatch _StopWatch;
    public MethodResult()
    {
        _StopWatch = new Stopwatch();
        _StopWatch.Start();
    }
    public object Result { get; set; }
    public TimeSpan ExecutionTime { get; set; }

    public void Dispose()
    {
        _StopWatch.Stop();
        ExecutionTime = _StopWatch.Elapsed;
    }
}

Usage:

static MethodResult TestMehodResult()
{
    using (var result = new MethodResult())
    {
        result.Result = 666;
        Thread.Sleep(1000);
        return result;
    }
}

My question is really simple: is implementing only Dispose() method is sufficient for this case, or should I implement the entire Dispose pattern in my class?
There are no resources to free in my class.

Bonus question: Is there a better pattern to measure execution time of a method instead of using an IDisposable like I did?

Sorry if this question is dumb. I'm really new to .net
Thanks in advance.

Upvotes: 1

Views: 125

Answers (2)

Marc Gravell
Marc Gravell

Reputation: 1062530

Yes, that's fine, but I'd probably advise "sealing" the class; there can be no question over whether it needs a more complex virtual Dispose(bool) API, finalizer support, if you simply declare it as:

public sealed class MethodResult : IDisposable

because now:

  • it can't be subclassed, so you know you don't need to deal with polymorphism
  • it doesn't have a finalizer, and you know that a subclass doesn't

So: very explicit and obvious.

Upvotes: 2

Funk
Funk

Reputation: 11201

To stay true to the concept of scope, you can inject your result in the IDisposable's constructor. Using an interface to keep things flexible. I'm surprised nobody mentioned the loss of type safety in your method, I'd definitely add the generic type parameter to the base MethodResult class (as you mention it to be in the comments).

public interface ITimed
{
    TimeSpan ExecutionTime { get; set; }
}

public class MethodResult<T> : ITimed
{
    public T Result { get; set; }
    public TimeSpan ExecutionTime { get; set; }
}

public class MethodTimer : IDisposable
{
    private readonly Stopwatch _StopWatch;
    private ITimed _result;

    public MethodTimer(ITimed result)
    {
        _result = result;
        _StopWatch = new Stopwatch();
        _StopWatch.Start();
    }

    public void Dispose()
    {
        _StopWatch.Stop();
        _result.ExecutionTime = _StopWatch.Elapsed;
        _result = null;
    }
}

Usage

static MethodResult<int> TestMehodResult()
{
    var timedResult = new MethodResult<int>();

    using (var timer = new MethodTimer(timedResult))
    {
        timedResult.Result = 666;
        Thread.Sleep(1000);
    }

    return timedResult;
}

Upvotes: 3

Related Questions