Pregunta

I try to write the following code and get an error

using (object obj = await command.ExecuteScalarAsync())
{
   //....
}

Implicitly convertible to System.IDisposable

How to solve that? I tried the cast (the static one doesn't work...)
If I don't use using and check that the object is not null I do the casting in the following way:

Convert.ToInt32(obj);

But I should use using

¿Fue útil?

Solución

You don't need to dispose in this case, simply do:

object obj = await command.ExecuteScalarAsync();

ExecuteScalarAsync returns a Task<T>, which you are subsequently awaiting. This "awaiting" will handle the task object, you get the result from the task/execution, which is very unlikely to require disposal.

Otros consejos

Using statement is only valid (and useful) with IDisposable objects. It gives you nothing if your object is not disposable. Basically, it's syntactic sugar for this equivalent code:

IDisposable obj = ...;
try
{
  ...
}
finally
{
  obj.Dispose();
}

The guys implementing the C# compiler simply decided that having the using statement available for classes that don't implement IDisposable would be useless and confusing.

It doesn't work in any way as with or some other statement that looks superficially similar. It will not affect garbage collection in any way (apart from perhaps limiting variable scope - but simple blocks ({ ... }) to the very same thing.

Safely getting the value is something completely different. You want to do something like this:

object val = await command.ExecuteScalarAsync();

if (val == DBNull.Value)
{
  // It's null
}
else
{
  int realValue = (int)val;
}

I agree with everyone that using is only useful with IDisposable and I can't think of a single reason that I would need to dispose of the scalar returned by ExucuteScaler. That said if you ever run into a method that does return a mix of disposable and non disposable values you can do this:

static void Main(string[] args)
{
    object obj1 = Foo();

    using (IDisposable disp = obj1 as IDisposable)
    {
        // operate on obj1 only since disp might be null
    }
}

using will just ignore a null value so if ojb1 doesn't support IDisposable the as will cast to null and everything works. If it does then the object is disposed.

I have never needed this bit of trivia because any method that returns a mix of IDisposable and non diposable objects is a bad design but it could happen someday. :-)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top