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

В чем разница между этими тремя способами очистки текстового поля?

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

Может кто-нибудь, пожалуйста, объясните мне об этом с некоторыми примерами?

  • txtUserName.Clear();
  • txtUserName.Text = string.Empty;
  • txtUserName.Text = "";
4b9b3361

Ответ 1

Метод Clear() делает больше, чем просто удаляет текст из TextBox. Он удаляет все содержимое и сбрасывает выбор текста и каретку, как приятно показывает @syned answer.

Для примера txtUserName.Text = ""; Framework создаст пустой объект string, если он еще не существует в пуле строк и установите его в свойство Text. Однако, если строка "" уже используется в приложении, тогда Framework будет использовать это значение из пула.

В примере txtUserName.Text = string.Empty; Framework не будет создавать пустой объект string, вместо этого ссылаясь на пустую константу строки и устанавливая это в свойство Text.

В тестах производительности было показано (в В С#, следует ли использовать string.Empty или String.Empty или ""? post), что там действительно нет никакой полезной разницы между двумя последними примерами. Вызов метода Clear() определенно самый медленный, но это явно потому, что он выполняет другую работу, а также очищает текст. Несмотря на это, разница в производительности между тремя параметрами остается практически незаметной.

Ответ 2

Если это не так глубоко:

Удалить: удалить содержимое из TextBox и может удалять ресурсы, выделенные с ним

    public void Clear()
    {
      using (this.TextSelectionInternal.DeclareChangeBlock())
      {
        this.TextContainer.DeleteContentInternal(this.TextContainer.Start, this.TextContainer.End);
        this.TextSelectionInternal.Select(this.TextContainer.Start, this.TextContainer.Start);
      }
    }

Назначение пустой строки (поскольку string.Empty и "" равны) для свойства Text просто назначают пустую строку прикрепленному свойству TextBox.TextProperty:

public string Text
{
  get
  {
    return (string) this.GetValue(TextBox.TextProperty);
  }
  set
  {
    this.SetValue(TextBox.TextProperty, (object) value);
  }
}

Ответ 3

Если вы столкнулись с некоторыми различиями в производительности или утечками памяти, их не так много (просто некоторые дополнительные вызовы при настройке текста вместо использования .Clear())

Однако у вас нет доступа к самому управлению при использовании MVVM, поэтому только очистить текст можно с помощью задавать текст привязанному свойству с помощью TextBox.

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

Ответ 4

Похоже, что он выполняет некоторые дополнительные вещи, такие как проверка происхождения изменений, привязки, обновление позиции каретки и отмена/очистка отменить. Большинство из которых, вероятно, не нужны при назначении пустой строки.

/// <summary>
/// Callback for changes to the Text property
/// </summary>
private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    TextBox textBox = (TextBox)d;
    bool inReentrantChange = false;
    int savedCaretIndex = 0;

    if (textBox._isInsideTextContentChange)
    {
        // Ignore property changes that originate from OnTextContainerChanged,
        // unless they contain a different value (indicating that a
        // re-entrant call changed the value)
        if (textBox._newTextValue != DependencyProperty.UnsetValue)
        {
            // OnTextContainerChanged calls
            //      SetCurrentDeferredValue(TextProperty, deferredTextReference)
            // Usually the DeferredTextReference will appear in the new entry
            if (textBox._newTextValue is DeferredTextReference)
            {
                if (e.NewEntry.IsDeferredReference &&
                    e.NewEntry.IsCoercedWithCurrentValue &&
                    e.NewEntry.ModifiedValue.CoercedValue == textBox._newTextValue)
                {
                    return;
                }
            }
            // but if the Text property is data-bound, the deferred reference
            // gets converted to a real string;  during the conversion (in
            // DeferredTextReference.GetValue), the TextBox updates _newTextValue
            // to be the string.
            else if (e.NewEntry.IsExpression)
            {
                object newValue = e.NewEntry.IsCoercedWithCurrentValue
                                    ? e.NewEntry.ModifiedValue.CoercedValue
                                    : e.NewEntry.ModifiedValue.ExpressionValue;
                if (newValue == textBox._newTextValue)
                {
                    return;
                }
            }
        }

        // If we get this far, we're being called re-entrantly with a value
        // different from the one set by OnTextContainerChanged.  We should
        // honor this new value.
        inReentrantChange = true;
        savedCaretIndex = textBox.CaretIndex;
    }

    // CoerceText will have already converted null -> String.Empty,
    // but our default CoerceValueCallback could be overridden by a
    // derived class.  So check again here.
    string newText = (string)e.NewValue;
    if (newText == null)
    {
        newText = String.Empty;
    }

    textBox._isInsideTextContentChange = true;
    try
    {
        using (textBox.TextSelectionInternal.DeclareChangeBlock())
        {
            // Update the text content with new TextProperty value.
            textBox.TextContainer.DeleteContentInternal((TextPointer)textBox.TextContainer.Start, (TextPointer)textBox.TextContainer.End);
            textBox.TextContainer.End.InsertTextInRun(newText);

            // Collapse selection to the beginning of a text box
            textBox.Select(savedCaretIndex, 0);
        }
    }
    finally
    {
        //
        if (!inReentrantChange)
        {
            textBox._isInsideTextContentChange = false;
        }
    }

    // We need to clear undo stack in case when the value comes from
    // databinding or some other expression.
    if (textBox.HasExpression(textBox.LookupEntry(TextBox.TextProperty.GlobalIndex), TextBox.TextProperty))
    {
        UndoManager undoManager = textBox.TextEditor._GetUndoManager();
        if (undoManager != null)
        {
            if (undoManager.IsEnabled)
                undoManager.Clear();
        }
    }
}

Ответ 5

"" создает объект, а String.Empty не создает объект. Таким образом, более эффективно использовать String.Empty.

Refference: String.Empty vs ""

Что касается .Clear(), я не получил лучшего ответа, а затем ответил @syned.

Ответ 6

Пропустите команды поочередно.

txtUserName.Clear();

Команда Clear() присваивает texbox пустую строку, как в следующем примере. Источник (лучшее объяснение дается синтаксисом в этой точке)

txtUserName.Text = string.Empty;

Теперь string.Empty код активации для него -

static String()
{
    Empty = "";
}

Значение того, что вы назначаете строку "" после времени компиляции.

txtUserName.Text = "";

Теперь вы просто назначаете строку "" непосредственно объекту во время компиляции.

Маленькая заметка txtUserName.Text = ""; быстрее, чем txtUserName.Text = string.Empty; Источник

Ответ 7

Поле string.Empty представляет собой пустой строковый литерал. Он немного отличается от пустой константы строки ". Существует тонкая разница, но это может быть значительным в некоторых сценариях. Он изменяет значение программы

Мы используем string.Empty и " в программе С#. Поле string.Empty инициализируется на" " во время выполнения .NET Framework.

Вы не можете использовать string.Empty в качестве случая переключения, потому что it cannot be determined at compile-time by the C# compiler.

Объяснение различий в string.empty и"

Метод Clear() делает больше, чем просто удаляет текст из TextBox. Он удаляет все содержимое и сбрасывает выбор текста

Ответ 8

Ну.. 1-е предупреждение, этот ответ имеет такой потенциал, чтобы быть вне существующего консенсуса большинства разработчиков здесь, но здесь идет:) попробуйте прочитать его до конца.

Эти два (и даже дополнительный, включенных мной) являются точно такими же:

txtUserName.Text = "";
txtUserName.Text = string.Empty;
txtUserName.Text = null;

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

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

Что касается третьего чувака txtUserName.Clear(), это другой случай, я предполагаю точно так же, как вы, что внутренняя реализация этого метода фактически или просто использует одно из этих трех назначений..
(и, как уже упоминалось, другие это даже больше, чем просто удаление символов из текста)
Однако, если вы считаете объектно-ориентированным - предположите, что кто-то хочет создать специальный текстовый ящик, который включает в себя, например, больше вещей, чтобы очистить его - для него будет очень удобно использовать этот метод "Очистить".. и если вы использовали clear - вы не меняете свой код при изменении основного текстового поля на новый пользовательский/специальный texbox.

Итак, чтобы подвести итог - если вы хотите использовать элемент управления, вы должны использовать его методы, а это значит, что использование этого метода Clear() будет более подходящим, если вы захотите его очистить, особенно если в один прекрасный день в будущем вы захотите заменить это текстовое поле собственным текстовым полем. поэтому по крайней мере грамматически это лучший выбор.
Но да, это приведет к повышению производительности, если все, что вам нужно, это просто удалить символы из свойства text.

Вот небольшая программа для проверки эффективности каждого из WPF.

<Window x:Class="WpfApplication4.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <TextBox Name="txtbx1" Grid.Row="0"/>
    <TextBox Name="txtbx2" Grid.Row="1"/>
    <TextBox Name="txtbx3" Grid.Row="2"/>
    <TextBox Name="txtbx4" Grid.Row="3"/>
</Grid>

using System;
using System.Windows;

namespace WpfApplication4
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            DateTime oldTime, newTime;
            TimeSpan delta;

            var iterations = 100000;

            #region Test performance 1

            oldTime = DateTime.Now;
            for (var i = 0; i < iterations; i++)
                txtbx1.Text = "";
            newTime = DateTime.Now;
            delta = newTime - oldTime;
            txtbx1.Text = delta.Milliseconds.ToString();

            #endregion

            #region Test performance 2

            oldTime = DateTime.Now;
            for (var i = 0; i < iterations; i++)
                txtbx2.Text = string.Empty;
            newTime = DateTime.Now;
            delta = newTime - oldTime;
            txtbx2.Text = delta.Milliseconds.ToString();

            #endregion

            #region Test performance 3

            oldTime = DateTime.Now;
            for (var i = 0; i < iterations; i++)
                txtbx3.Text = null;
            newTime = DateTime.Now;
            delta = newTime - oldTime;
            txtbx3.Text = delta.Milliseconds.ToString();

            #endregion

            #region Test performance 4

            oldTime = DateTime.Now;
            for (var i = 0; i < iterations; i++)
                txtbx4.Clear();
            newTime = DateTime.Now;
            delta = newTime - oldTime;
            txtbx4.Text = delta.Milliseconds.ToString();

            #endregion
        }
    }
}

Это были результаты, которые я получил: 43, 40, 73, 443

И это согласовано - первые два примерно одинаковы +/- мини-секунда или две, третий всегда немного длиннее, а последний, безусловно, длиннее всех остальных.

Я думаю, что это так глубоко, как это получается:)

Ответ 9

txtUserName.Clear();

Этот код очищает текстовое поле. Он установит для значения "Текстовое поле" значение ""

txtUserName.Text = string.Empty;

Не создает объект. Это выполняется быстрее, чем txtUserName.Text = "";

txtUserName.Text = "";

Создает объект и влияет на производительность.

Ответ 10

Некоторые говорят, что String.Empty быстрее, чем ", однако String.EMpty является статическим членом, который инициализируется " "

Когда мы вызываем String.Empty, IL вызывает вызов

mscorlib.dll 

IL_0007:  ldsfld     string [mscorlib]System.String::Empty

В то время как для "" это не

IL_001a:  ldstr      ""

SO логически более разумно, что " более эффективен, чем String.Empty