Реальное использование для 'как' и

Что-то, что я не видел упомянутый к настоящему времени: люди, которые знают базу данных лучше всего, являются не всегда людьми, которые пишут код приложения. Хранимые процедуры дают людям базы данных способ взаимодействовать через интерфейс с программистами, которые действительно не хотят узнавать так много о SQL. Большой - и особенно наследие - базы данных не являются самыми легкими вещами полностью понять, таким образом, программисты могли бы просто предпочесть простой интерфейс, который дает им, в чем они нуждаются: позвольте DBAs выяснить, как присоединиться к этим 17 таблицам, чтобы заставить это произойти.

Однако языки раньше писали, что хранимые процедуры (МН / SQL известный пример) являются довольно жестокими. Они обычно не предлагают ни одной из тонкостей, которые Вы видели бы в сегодняшнем популярном императиве, ООП или функциональных языках. Думайте КОБОЛ.

Так, придерживайтесь хранимых процедур, что просто абстрактный далеко реляционные детали, а не те, которые содержат бизнес-логику.

14
задан David Basarab 15 October 2009 в 13:14
поделиться

14 ответов

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

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

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

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

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

и так далее. . Без , поскольку и равно , это было бы намного сложнее, ИМХО.

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

Marc

34
ответ дан 1 December 2019 в 05:49
поделиться

Пользовательские преобразователи типов сначала приходят на ум.

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;
      //...
}
1
ответ дан 1 December 2019 в 05:49
поделиться

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

1
ответ дан 1 December 2019 в 05:49
поделиться

Вот один, который часто всплывает:

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.
     }
}
10
ответ дан 1 December 2019 в 05:49
поделиться

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

Другой, 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's a button
    }
    catch(InvalidCastException ice)
    {
        // click did not come from a button! Handle other cases
    }
}

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

8
ответ дан 1 December 2019 в 05:49
поделиться

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

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

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

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

3
ответ дан 1 December 2019 в 05:49
поделиться

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

2
ответ дан 1 December 2019 в 05:49
поделиться

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

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

1
ответ дан 1 December 2019 в 05:49
поделиться

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

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 фактически проверяет тип объекта дважды: сначала проверяет оператор is чтобы узнать, совместим ли o с типом Employee. Если это так, то внутри оператора if CLR снова проверяет, что o относится к Employee при выполнении преобразования.

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

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

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

2
ответ дан 1 December 2019 в 05:49
поделиться

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

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

или

int personHeight = dr["Height"] as int? ?? 0;
7
ответ дан 1 December 2019 в 05:49
поделиться

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

protected void SomeButtonInAGridView_Click(object sender, EventArgs e)
{
    Button clickedButton = sender as Button;
}
15
ответ дан 1 December 2019 в 05:49
поделиться

If you're really never having to do casting then I you likely wouldn't have much use for these operators. In my experience, however, .NET programming calls for a lot of casting particularly when dealing with delegates where arguments are provided typed as 'object'. I think that the introduction of generics has helped cut down on the need for casting, but it's certainly something that I use pretty often. I might be "doing it wrong" but that's just been my experience.

So if you're going to do casting anyway I really like the 'is' operator for improved readability of the code. I'd much rather look at

if(foo is SomeType) {...}

then

if(foo.GetType() == typeof(SomeType)) {...}
0
ответ дан 1 December 2019 в 05:49
поделиться

Here's another use-case to go into the Cabinet of Dr. Caligari ;-)

You can chain the as operator, as in:

x = obj as Label as Control;

Why would you do such a thing? If you want null if its not a Label, but you want to treat them all as Control. Just casting Textbox and Label directly to Control would yield success for both, now it'll be null for unwanted types of Control. This is a shortcut method you won't need often but is occasionally handy.

An alternative use for the same is when you need ToString() on an object, but only when it is of the correct type, otherwise you want a default string. This is a scenario that I do encounter very often, esp. with POCOs. Because ToString() is virtual, this works:

// 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();
2
ответ дан 1 December 2019 в 05:49
поделиться

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 с как . Когда вы когда-либо используете вместо , просто заменяйте его приведенным выше выражением, оно эквивалентно. Использование равно с прямым приведением () или как только само по себе. Лучше написать этот пример.

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 
}

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

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

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

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

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

int x = o as int;

if (x != null)
   ???

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

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

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

Рассмотрим следующий код

int x = o as int;

if (x != null)
   ???

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

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

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

Рассмотрим следующий код

int x = o as int;

if (x != null)
   ???

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

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

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

0
ответ дан 1 December 2019 в 05:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: