2010-10-03 13 views
7

Si un objeto se da cuenta de IDisposable en C# se puede escribir¿Está 'usando' una palabra clave C#?

using(DisposableFoo foo = new DisposableFoo()) 

Siempre me he preguntado por qué el using se parece a una palabra clave de C#, pero requiere una interfaz definida en el marco .Net. ¿Es using una palabra clave (en este contexto, obviamente, es para definir las importaciones de su biblioteca), o Microsoft sobrecargó su uso en Visual Studio/.Net framework? No esperaba que una palabra clave C# dependiera de una biblioteca.

+6

no veo cuál es el problema con una palabra clave que requiere sus "argumentos" para implementar una interfaz. 'foreach' es también una palabra clave y requiere que la colección sea' IEnumerable'. – sepp2k

+3

@ sepp2k - punto pedante: * NO * necesita IEnumerable for foreach. –

+0

@Marc Gravell: ¿Qué quieres decir? de acuerdo con un enlace msdn dice "System.Collections.IEnumerable o System.Collections.Generic.IEnumerable " http://msdn.microsoft.com/en-us/library/ttw7t8t6.aspx –

Respuesta

6

Sí, es una palabra clave. El lenguaje C# se basa en el marco para implementar muchas palabras clave.

Otras palabras clave que se basan en el marco es para exmaple foreach (utiliza IEnumerable) y la sintaxis de LINQ (cuando se utiliza con LINQ a objetos requiere la biblioteca System.Linq).

Incluso las palabras clave como int y string se basan en los tipos System.Int32 y System.String en el marco.

+3

En realidad, usar es poco común * porque * requiere una interfaz. Puede usar foreach sin IEnumerable, y LINQ sin bibliotecas especiales (ni siquiera necesita métodos de extensión, en realidad) –

+1

@Mark Gravell: Creo que en realidad es extraño porque usa un tipado de pato que no es característico de C# , que requiere la implementación de IEnumerable, pero no la interfaz real. Aclararé que es LINQ to Objects que requieren la biblioteca System.Linq. – Guffa

+0

@guffa LINQ, lo que significa que la sintaxis de consulta de idioma no requiere ninguna biblioteca específica. Podría escribir una aplicación de consola C# 3/.net 2.0 que use la sintaxis de consulta LINQ. –

1

Creo usando es una palabra clave que esencialmente hacer que el código

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 
} 

en

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(); 
} 

la parte importante de por qué se utiliza IDisposable se debe a que C# es fuertemente tipado, detrás de las escenas de su vocación Dispose(), y la implementación de IDisposable le dice al compilador que puede.

Similar a cómo foreach es con IEnumerable y el IEnumerator (llamando a GetEnumerator(), Current(), MoveNext() aunque creo que esto no hace con las matrices solo las clases de colección).

+0

Creo que el uso (A = un nuevo A(), C c = nuevo C()) no funcionará. El compilador devuelve este mensaje: "No se puede usar más de un tipo en un enunciado for, using o declaration". Sé que es solo un detalle de lo que estabas explicando, pero nadie lo mencionó y eso es lo que estaba buscando. – Alpha

8

es una construcción de palabra clave que requiere un IDisposable, porque actúa sobre el método Dispose del objeto. No es demasiado exagerado tener una palabra clave para usar un tipo. Si es una palabra clave y requiere una condición (IE: Boolean) escriba.

4

C# está ligado hadas estrechamente a la CLI y la especificación de lenguaje utiliza un número mínimo de características de tiempo de ejecución. IDisposable para "usar" es inusualmente rígido, ya que en la mayoría de los casos (por ejemplo, "foreach", LINQ, etc.) existe compatibilidad con y sin la implementación específica del tiempo de ejecución.

Sin embargo, dado que el constructo IDisposable/using es la clave de .NET, dudo que pueda crear incluso una CLI mínima (pero legal) sin ella, por lo que no es realmente un problema mencionarlo en la especificación del idioma.

Otras cosas que atan a tipos específicos:

  • concatenación de cadenas (+ vs cadena.Concat)
  • métodos de extensión
  • genérico nuevo()
  • [Serializable] (mapas a una bandera IL, no un atributo)
  • foreach (pero se puede utilizar sin ninguna de las interfaces)
  • núcleo tipos de bases (Enum matriz de objetos ValueType de delegado)
  • compilador expresión-árbol (pero ni descritos en la especificación)

Etc

2

Sí, definitivamente existe un acoplamiento entre el lenguaje y los ensamblajes de soporte en .NET framework. Con mucho, el más importante es mscorlib.dll, el hogar de la declaración de interfaz System.IDisposable. Es tan importante que ni siquiera aparece en el nodo Referencias del proyecto C#. El compilador de C# supone que siempre es necesario y lo encontrará solo, a menos que use la opción de compilación especial/nostdlib.

Otros ejemplos de elementos sintácticos que lo requieran:

  • array [], requiere System.Array
  • [atributos], requiere System.Attribute
  • captura, requiere System.Exception
  • delegar, requiere System.MulticastDelegate
  • tipo ?, requiere System.Nullable <>
  • params, r equires System.ParamArrayAttribute
  • typeof, requiere System.Type

hay acoplamiento entre todos los tipos básicos y su correspondiente declaración en mscorlib (como Int32, String, Object, ValueType etc).

Los ejemplos posteriores son la sintaxis de comprensión de consultas Linq, que requiere System.Core.dll y la palabra clave dinámica, que requiere Microsoft.CSharp.dll. Estos ejemplos no son exhaustivos.

Esto es bastante normal, incluso los compiladores C suponen que una biblioteca de tiempo de ejecución está disponible con primitivos como memset() y ldiv().

1

using es una palabra clave C# que actúa como un azúcar sintáctico para tratar con objetos IDisposibles. Según MSDN

usando bloque Define un ámbito, fuera del cual se eliminarán un objeto u objetos.

La instrucción using permite al programador especificar cuándo los objetos que usan recursos deberían liberarlos. El objeto proporcionado a la instrucción using debe implementar la interfaz IDisposable. Esta interfaz proporciona el método Dispose, que debería liberar los recursos del objeto.

Sorprendentemente, incluso MSDN no aclara cómo sucede esto bajo el capó. Solo dice que el objeto tiene que implementar una interfaz IDisposable que proporcione el método Dispose en el objeto que implementa la interfaz.Por lo tanto, para disponer del objeto necesitará llamar al método Dispose en el objeto que limpiará y liberará los recursos utilizados por el objeto.

Tome un vistazo a este ejemplo ..

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(); 
      } 
     } 
    } 
} 

compilador convierte a código para tener este aspecto ..

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(); 
      } 
     } 
    } 
} 

Para entender cómo funciona exactamente los bloques utilizando bajo el capó, recomiendo lees esto blog-post.

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

+1

En realidad, diría que es una buena cosa que MSDN no diga lo que sucede debajo del capó. Bastantes cosas, los detalles de MSDN brindan detalles de implementación sin demasiadas explicaciones sobre qué es un detalle de implementación y qué se requiere (pila versus montón cuando se trata de valores y tipos de referencia sería un ejemplo clásico). Sería mejor en algunos aspectos si los separaran mejor. Si ** también ** la implementación detallada sería agradable, pero prefiero que el texto normativo detalle la información normativa. –

Cuestiones relacionadas