Подтвердить что ты не робот

Реальное использование для `as` и` is`

Я использую as или is в С# или любом языке, который поддерживает ключевое слово.

Для чего вы его использовали?

Я не имею в виду, как я его использую, я имею в виду, как вам это действительно нужно?

Мне также удалось избежать придания нет типичности в довольно большом проекте С++ (я был горд).

Итак, учитывая, что я почти никогда не задаю тип, почему мне нужно ключевое слово as или is?

4b9b3361

Ответ 1

Мне пришлось написать код, чтобы перечислять все элементы управления, размещенные на веб-странице ASP.NET, и выполнять определенные операции над конкретными элементами управления, например. добавить цвет фона ко всем текстовым полям и т.д.

Основное преимущество as и is для меня в том, что я могу с уверенностью проверить, имеет ли переменная данный тип с использованием is без каких-либо исключений. Как только я уверен, что это определенный тип, я могу безопасно и легко преобразовать его в тип, необходимый с помощью as.

Что я в основном делал (упрощен!) - это

foreach(Control c in form.Controls)
{
   if(c is Textbox)
      HandleTextbox(c as Textbox);

   if(c is Listbox)
      HandleListbox(c as Listbox);
}

и т.д. Без as и is это было бы намного беспощадно, ИМХО.

В принципе, вам, вероятно, понадобится или может хорошо использовать as и is, если вы имеете дело с полиморфизмом - если у вас есть списки вещей, которые могут быть любого количества типов, например, элементов управления на страницу в моем примере. Если вы не имеете или не используете полиморфизм много, вы вряд ли столкнетесь с необходимостью для этих операторов.

Марк

Ответ 2

Я использую "как" как удобный ярлык в обработчиках событий, чтобы вернуть объект отправки, когда я не могу знать во время разработки отправителя.

protected void SomeButtonInAGridView_Click(object sender, EventArgs e)
{
    Button clickedButton = sender as Button;
}

Ответ 3

Здесь один, который появляется много:

class Foo {
     public override bool Equals(object obj)
     {
         // The more specific function needs to do null checking anyway.
         return Equals(obj as Foo);
     }

     public bool Equals(Foo obj)
     {
         // do some comparison here.
     }
}

Ответ 4

Интригующий вопрос. На самом деле, я использую их все время. is удобно узнать, имеет ли объект определенный тип, я иногда использую это в generics или в циклах через объекты, которые имеют разные типы. Это также бесценно с отражением.

Другой, as находит много других применений. Часто гораздо безопаснее использовать обычный прилив: когда он терпит неудачу, он возвращает null вместо исключения. Я также нахожу его более четким синтаксисом и проще его использовать, проверьте возвращаемое значение для null, а затем добавьте блок исключений.

В принципе, я хочу сказать, я предпочитаю это:

protected void GeneralEventHandler(object sender, EventArgs e)
{
    Button btn = sender as Button;
    if(btn != null)   // click came from a button!
        // do something
    else
        // other cases
}

и это:

protected void GeneralEventHandler(object sender, EventArgs e)
{
    if(sender is Button)   // click came from a button!
        // do something
    else
        // other cases
}

в отличие от этого:

protected void GeneralEventHandler(object sender, EventArgs e)
{
    try 
    {
        Button btn = (Button) sender;
        // if we get this far, it a button
    }
    catch(InvalidCastException ice)
    {
        // click did not come from a button! Handle other cases
    }
}

конечно, это всего лишь пример, но когда я смогу избежать try/catch, я это сделаю. Это также дает больше возможностей для реальных исключений.

Ответ 5

Я использую его для чистого получения данных из DataReader, который может быть DBNull.

int? personHeight = dr["Height"] as int?;

или

int personHeight = dr["Height"] as int? ?? 0;

Ответ 6

Вот сообщение от Эрика Липперта, описывающее, как "как" используется в С#:

http://blogs.msdn.com/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx

Я использую все время. Когда мне нужно отменить сериализованный объект из кеша сеанса, я использую его, чтобы определить, существует ли сериализованный объект и нужного типа. Я могу избежать того, чтобы программа выдавала ошибку, используя оператор as и проверяя значение null. Если он равен нулю, я знаю, что чего-то не хватает, и я могу воссоздать объект и вставить его обратно в кеш в следующий раз, когда он мне понадобится.

Вы можете выполнить тот же результат с помощью оператора трансляции, но это добавляет накладные расходы исключения, особенно если вы знаете, что сериализованный объект не будет частью времени.

Ответ 7

С# предлагает способ использования с использованием оператора is и as. Оператор-оператор проверяет, объект совместим с данным типом, а результат оценки - логический: истинный или false. Оператор никогда не будет генерировать исключение. Следующий код демонстрирует:

System.Object o = new System.Object();
System.Boolean b1 = (o is System.Object); // b1 is true.
System.Boolean b2 = (o is Employee); // b2 is false.

Если ссылка объекта равна нулю, оператор is всегда возвращает false, потому что нет объект доступен для проверки его типа.

Оператор is обычно используется следующим образом:

if (o is Employee) {
Employee e = (Employee) o;
// Use e within the ‘if’ statement.
}

В этом коде CLR фактически проверяет тип объектов дважды: оператор сначала проверяет чтобы узнать, совместим ли он с типом Employee. Если это так, то внутри оператора if CLR снова проверяет, что o относится к Работнику при выполнении броска.

С# предлагает способ упростить этот код и улучшить его производительность, предоставляя оператора:

Employee e = o as Employee;
if (e != null) {
// Use e within the ‘if’ statement.
}

В этом коде CLR проверяет, совместим ли o с типом Employee, а если это так, возвращает ненулевой указатель на тот же объект. Если o несовместимо с типом Employee, то оператор as возвращает null.

Ответ 8

Если вы когда-либо разрабатывали проект, предлагающий интерфейс плагина, то as и is быстро станут вашими хорошими друзьями ОЧЕНЬ.

Ответ 9

Вот еще один случай использования, чтобы войти в кабинет доктора Калигари; -)

Вы можете связать оператор as, как в:

x = obj as Label as Control;

Зачем ты так поступаешь? Если вы хотите, чтобы null, если это не метка, но вы хотите рассматривать их все как Control. Простое литье текстового поля и ярлыка непосредственно в элемент управления приведет к успеху для обоих, теперь это будет null для нежелательных типов элементов управления. Это метод быстрого доступа, который вам не понадобится часто, но иногда удобен.

Альтернативное использование для этого - это когда вам нужно ToString() для объекта, но только когда он имеет правильный тип, в противном случае вы хотите использовать строку по умолчанию. Это сценарий, с которым я встречаюсь очень часто, особенно. с POCOs. Поскольку ToString() является виртуальным, это работает:

// assume SomeClass has overridden ToString()
// return "none" if item is not of type SomeClass or if it is null to begin with
string itemText = (item as SomeClass as Object ?? "none").ToString();

Ответ 10

Присвоения в стиле C (например, (Foo)bar) будут бросать InvalidCastException, если сбрасывание происходит. as, с другой стороны, даст null (см. this). Оператор is просто используется для проверки того, совместим ли тип времени выполнения данного экземпляра с предоставленным типом (см. this).

is широко используется в .NET System.ComponentModel пространстве имен. Более конкретно, TypeConverter API в значительной степени зависит от оператора is, чтобы определить, как преобразовать из одного типа в другой.

Ответ 11

Я использовал оба ключевых слова широко в приложении WinForms, где есть графический интерфейс для редактирования счета-фактуры, каждая строка в ListView может содержать различные типы элементов (т.е. это может быть позиция или описание, или...). Все элементы, помещенные в ListView, были получены из ListViewItem, поэтому позже, когда я пошел, чтобы реализовать такие вещи, как редактирование выбранного элемента, мне пришлось проверить, какой тип элемента был выбран (с помощью is), чтобы показать соответствующий графический интерфейс редактирования.

Ответ 12

Пользовательский TypeConverters приходит на ум первым.

public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if (value is string)
            {
                return GetEnumValue(myVal, (string)value);
            }
            if (value is Enum)
            {
                return GetEnumDescription((Enum)value);
            }
            return base.ConvertFrom(context, culture, value);
        }

Вторым является случай, когда у меня есть тень объекта (для отслеживания изменений), который наследуется от базового класса

class BaseClass
{
    BaseClass _shadow;
}

protected override void UpdateShadow()
{
    ThisClass shadow = _shadow as ThisClass;
      //...
}

Ответ 13

Если вам действительно не нужно делать кастинг, то я, скорее всего, не буду использовать их для этих операторов. Однако, по моему опыту,.NET-программирование требует большого количества кастингов, особенно при работе с делегатами, где аргументы предоставляются как "объект". Я думаю, что введение дженериков помогло сократить необходимость кастинга, но это, безусловно, то, что я использую довольно часто. Я мог бы "делать это неправильно", но это был только мой опыт.

Итак, если вы собираетесь делать кастинг, мне очень нравится оператор 'is' для улучшения чтения кода. Я бы скорее посмотрел на

if(foo is SomeType) {...}

затем

if(foo.GetType() == typeof(SomeType)) {...}

Ответ 14

marc_s ответ немного испорчен, я все время вижу этот код, поэтому хочу подчеркнуть важность различия между этими операторами. is - это логический тест, чтобы определить, может ли объект назначаться определенному типу. as проверяет, назначен ли объект определенному типу, и если он есть, он возвращает этот объект как этот тип, если нет, он возвращает значение null. marc_s ответ действительно делает это

foreach(Control c in form.Controls)
{
   if(c is Textbox)
      HandleTextbox(c is Textbox ? (Textbox)c : null);

   if(c is Listbox)
      HandleListbox(c is Listbox ? (Listbox)c : null);
}

Нельзя использовать is с as. Когда вы используете as, просто замените его выражением выше, это эквивалентно. Используйте is только с прямыми трансляторами () или as. Лучше всего написать этот пример.

foreach(Control c in form.Controls)
{
   if(c is Textbox)
      HandleTextbox((Textbox)c); 
      //c is always guaranteed to be a Textbox here because of is 

   if(c is Listbox)
      HandleListbox((Listbox)c); 
      //c is always guaranteed to be a Listbox here because of is 
}

Или, если вам действительно нравится as

foreach(Control c in form.Controls)
{
   var textBox = c as Textbox;
   if(textBox != null) 
   {
       HandleTextbox(textBox);
       continue;
   }

   var listBox = c as ListBox
   if(listBox != null)
      HandleListbox(listBox);
}

Настоящим примером, на котором я все время сталкиваюсь, является получение объектов из области хранения, которые возвращают только объект типа. Кэширование - отличный пример.

Person p;
if (Cache[key] is Person)
    p = (Person)Cache[key];
else 
    p = new Person();

Я использую as гораздо меньше в реальном коде, потому что он действительно работает только для ссылочных типов. Рассмотрим следующий код

int x = o as int;

if (x != null)
   ???

as терпит неудачу, поскольку int не может быть нулевым. is работает нормально, хотя

int x;
if (o is int)
    x = (int)o; 

Я уверен, что между этими операторами существует определенная разница в скорости, но для реального приложения разница незначительна.