开发者

Is 'using' a C# keyword?

开发者 https://www.devze.com 2023-01-18 18:23 出处:网络
If an object realizes IDisposable in C# one can write using(DisposableFoo foo = new DisposableFoo()) I\'ve always wondered why the using looks like a C# keyword, but requires an interface defined i

If an object realizes IDisposable in C# one can write

using(DisposableFoo foo = new DisposableFoo())

I've always wondered why the using looks like a C# keyword, but requires an interface defined in the .Net framework. Is using a keyword (in this context, obviously it is for defining your library imports), or has Microsoft overloaded开发者_开发技巧 it's use in Visual Studio/.Net framework? I wouldn't have expected a C# keyword to depend on a library.


it's a keyword construct that requires a IDisposable, because it acts on the object's Dispose method. It's not too far fetched to have a keyword use a type. If is a keyword and it requires a condition (IE: Boolean) type.


According to Microsoft it's a keyword.


Yes, it is a keyword. The C# language relies on the framework for implementing many keywords.

Other keywords that rely on the framework is for exmaple foreach (uses IEnumerable) and the LINQ syntax (when used with LINQ to Objects requires the System.Linq library).

Even keywords like int and string rely on the types System.Int32 and System.String in the framework.


C# is tied fairy closely to the CLI, and the language spec uses a minimal number of runtime features. IDisposable for "using" is actually unusually rigid, as in most cases (for example "foreach", LINQ, etc) there is support both with and without the specific runtime implementation.

However, since the IDisposable /using construct is key to .NET I doubt you could make even a minimal (but legal) CLI without it, so it isn't really a problem to mention it in the language spec.

Other things that tie to specific types:

  • string concatenation (+ vs string.Concat)
  • extension methods
  • generic new()
  • [Serializable] (maps to an IL flag, not an attribute)
  • foreach (but can be used without any of the interfaces)
  • core base types (Enum Array Object ValueType Delegate)
  • expression-tree compiler (but nor described in the spec)

Etc


Yes, there is a definitely coupling between the language and the support assemblies in the .NET framework. By far the most important one is mscorlib.dll, the home for the System.IDisposable interface declaration. It is so important that it isn't even listed in your C# project's References node. The C# compiler assumes it is always needed and will find it by itself, unless you use the special /nostdlib compile option.

Other examples of syntactic elements that require it:

  • array[], requires System.Array
  • [attributes], requires System.Attribute
  • catch, requires System.Exception
  • delegate, requires System.MulticastDelegate
  • type?, requires System.Nullable<>
  • params, requires System.ParamArrayAttribute
  • typeof, requires System.Type

There's coupling between all the basic types and their corresponding declaration in mscorlib (like Int32, String, Object, ValueType etc).

Later examples are the Linq query comprehension syntax, requiring System.Core.dll, and the dynamic keyword, requiring Microsoft.CSharp.dll. These examples are by no means exhaustive.

This is otherwise quite normal, even C compilers assume that a runtime library is available with primitives like memset() and ldiv().


I think using is a keyword that essentially make your code

B b=new B();//can get resource outside using statement but will dispose inside of it
using(A a=new A(),b,C c=new C() //A,B,C are variable of types that implement IDisposable){
SomeCode//Some code to execute
}

into

B b= new B();
try{ 
A a= new A();
C c= new C();//B isn't here since

SomeCode//execute the code

}finallly{
a.Dispose();//The reason A,B,C need to implement IDisposable
b.Dispose();//is so the compiler can make sure that they can call Dispose()
c.Dispose();
}

The important bit with why IDisposable is used is because c# is strongly typed, behind the scenes its calling Dispose(), and implementing IDisposable tells the compiler it can.

Similar to how foreach is with IEnumerable and the IEnumerator (calling GetEnumerator(),Current(),MoveNext() although I think it doesn't do this with arrays only collection classes).


using is a C# keyword that acts as a syntactic-sugar for dealing with IDisposible objects. As per MSDN

using block Defines a scope, outside of which an object or objects will be disposed.

The using statement allows the programmer to specify when objects that use resources should release them. The object provided to the using statement must implement the IDisposable interface. This interface provides the Dispose method, which should release the object’s resources.

Surprisingly even MSDN does not clarify how does this happen under the hood. It only says the object has to implement IDisposable interface that provides Dispose method on the object implementing the interface. So to dispose the object it will need to call the Dispose method on the object which will cleanup and release the resources used by the object.

Take a look at this example..

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BlogSamples
{
    class Program
    {
        static void Main(string[] args)
        {
            //Assume that Car is IDisposible.
            using (Car myCar = new Car(1))
            {
                myCar.Run();
            }
        }
    }
}

Compiler converts to code to look like this..

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BlogSamples
{
    class Program
    {
        static void Main(string[] args)
        {
            //Declare myCar object with FullName of the type as seen in IL.
            BlogSamples.Car myCar;

            //Instantiate the object by calling the constructor, matching the flow of IL.
            myCar = new Car(1);

            try
            {
                myCar.Run();
            }
            finally
            {
                if(myCar != null)
                    myCar.Dispose();
            }
        }
    }
}

To understand how exactly the using block works under the hood, I recommend you read this blog-post.

http://www.ruchitsurati.net/index.php/2010/07/28/understanding-%E2%80%98using%E2%80%99-block-in-c/

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号