Используете ли вы ключевое слово C #? - PullRequest
7 голосов
/ 03 октября 2010

Если объект реализует IDisposable в C #, можно написать

using(DisposableFoo foo = new DisposableFoo())

Мне всегда было интересно, почему using выглядит как ключевое слово C #, но требует интерфейса, определенного в .Net framework. Является ли using ключевым словом (в данном контексте, очевидно, оно предназначено для определения импорта вашей библиотеки), или Microsoft перегружена его использованием в среде Visual Studio / .Net? Я бы не ожидал, что ключевое слово C # будет зависеть от библиотеки.

Ответы [ 7 ]

8 голосов
/ 03 октября 2010

это конструкция ключевого слова, которая требует IDisposable, потому что она действует на метод Dispose объекта. Это не слишком далеко, чтобы иметь ключевое слово использовать тип. If является ключевым словом и требует тип условия (IE: Boolean).

7 голосов
/ 03 октября 2010

Согласно Microsoft это ключевое слово.

6 голосов
/ 03 октября 2010

Да, это ключевое слово.Язык C # опирается на каркас для реализации многих ключевых слов.

Другие ключевые слова, которые опираются на каркас, относятся к примеру foreach (использует IEnumerable) и синтаксис LINQ (при использовании с LINQ to Objects требуетсяSystem.Linq library).

Даже ключевые слова, такие как int и string, используют в структуре типы System.Int32 и System.String.

4 голосов
/ 03 октября 2010

C # привязан фея близко к CLI, а языковая спецификация использует минимальное количество функций времени выполнения. IDisposable для «использования» на самом деле необычно жесткая, поскольку в большинстве случаев (например, «foreach», LINQ и т. Д.) Есть поддержка как с конкретной реализацией среды выполнения, так и без нее.

Однако, поскольку конструкция IDisposable / using является ключом к .NET, я сомневаюсь, что вы могли бы создать даже минимальный (но допустимый) CLI без него, поэтому упоминать об этом в спецификации языка не составляет особой проблемы. *

Другие вещи, которые относятся к определенным типам:

  • конкатенация строк (+ vs string.Concat)
  • методы расширения
  • универсальный новый ()
  • [Сериализуемый] (отображается на флаг IL, а не на атрибут)
  • foreach (но может использоваться без какого-либо интерфейса)
  • базовые базовые типы (Enum Array Object ValueType Delegate)
  • компилятор дерева выражений (но не описан в спецификации)

Etc

2 голосов
/ 03 октября 2010

Да, существует определенная связь между языком и вспомогательными сборками в .NET Framework.Безусловно, наиболее важным является mscorlib.dll, дом для объявления интерфейса System.IDisposable.Это так важно, что его даже нет в списке ссылок вашего проекта C #.Компилятор C # предполагает, что он всегда нужен, и найдет его сам, если только вы не используете опцию компиляции special / nostdlib.

Другие примеры синтаксических элементов, которым это требуется:

  • массив[], требуется System.Array
  • [атрибуты], требуется System.Attribute
  • перехват, требуется System.Exception
  • делегат, требуется System.MulticastDelegate
  • type ?, требуется System.Nullable <>
  • params, требуется System.ParamArrayAttribute
  • typeof, требуется System.Type

Существует связь между всеми основными типамии соответствующее объявление в mscorlib (например, Int32, String, Object, ValueType и т. д.).

Более поздние примеры - синтаксис понимания запросов Linq, требующий System.Core.dll, и ключевое слово dynamic , требующий Microsoft.CSharp.dll.Эти примеры ни в коем случае не являются исчерпывающими.

В остальном это вполне нормально, даже компиляторы C предполагают, что библиотека времени выполнения доступна с такими примитивами, как memset () и ldiv ().

1 голос
/ 03 октября 2010

using - это ключевое слово C #, которое действует как синтаксический сахар для работы с IDisposible объектами.Согласно MSDN

using block Определяет область действия, за пределами которой будет удален объект или объекты.

Оператор using позволяет программисту указывать, когда объекты, которые используютресурсы должны освободить их.Объект, предоставленный оператору using, должен реализовывать интерфейс IDisposable.Этот интерфейс предоставляет метод Dispose, который должен высвобождать ресурсы объекта.

Удивительно, но даже MSDN не проясняет, как это происходит под капотом.Это только говорит, что объект должен реализовать интерфейс IDisposable, который предоставляет метод Dispose для объекта, реализующего интерфейс.Поэтому для удаления объекта необходимо вызвать метод Dispose для объекта, который очистит и освободит ресурсы, используемые объектом.

Посмотрите на этот пример.

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

Компилятор преобразует код в следующий вид:

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

Чтобы понять, как именно работает блок «под капотом», я рекомендую прочитать это сообщение в блоге .

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

1 голос
/ 03 октября 2010

Я думаю, что использование - это ключевое слово, которое по сути делает ваш код

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
}

в

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

Важный аспект использования IDisposable заключается в том, что c # строго типизирован, за кулисами вызывается метод Dispose (), а реализация IDisposable сообщает компилятору, что он может.

Аналогично тому, как foreach работает с IEnumerable и IEnumerator (вызывая GetEnumerator (), Current (), MoveNext (), хотя я думаю, что он не делает это только с массивами классов коллекции).

...