Действительно ли возможно осуществить рефакторинг этот дополнительный метод?

Сравнительные тесты Производительности

Catch exception:
   10,000 good:    63,668 ticks
   10,000 bad:  6,435,609 ticks

Regex Pre-Screen:
   10,000 good:   637,633 ticks
   10,000 bad:    717,894 ticks

COM Interop CLSIDFromString
   10,000 good:   126,120 ticks
   10,000 bad:     23,134 ticks

Межглавный (Самый Быстрый) Ответ COM:

/// <summary>
/// Attempts to convert a string to a guid.
/// </summary>
/// <param name="s">The string to try to convert</param>
/// <param name="value">Upon return will contain the Guid</param>
/// <returns>Returns true if successful, otherwise false</returns>
public static Boolean TryStrToGuid(String s, out Guid value)
{
   //ClsidFromString returns the empty guid for null strings   
   if ((s == null) || (s == ""))   
   {      
      value = Guid.Empty;      
      return false;   
   }

   int hresult = PInvoke.ObjBase.CLSIDFromString(s, out value);
   if (hresult >= 0)
   {
      return true;
   }
   else
   {
      value = Guid.Empty;
      return false;
   }
}


namespace PInvoke
{
    class ObjBase
    {
        /// <summary>
        /// This function converts a string generated by the StringFromCLSID function back into the original class identifier.
        /// </summary>
        /// <param name="sz">String that represents the class identifier</param>
        /// <param name="clsid">On return will contain the class identifier</param>
        /// <returns>
        /// Positive or zero if class identifier was obtained successfully
        /// Negative if the call failed
        /// </returns>
        [DllImport("ole32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = true)]
        public static extern int CLSIDFromString(string sz, out Guid clsid);
    }
}
<час>

Нижняя строка: Если необходимо проверить, является ли строка гуидом, и Вы заботитесь о производительности, используете COM Interop.

, Если необходимо преобразовать гуид в Строковом представлении к Гуиду, используйте

new Guid(someString);
27
задан Matthew Murdoch 9 December 2009 в 11:34
поделиться

6 ответов

Нет, вы не можете этого сделать. Было бы неплохо, но это невозможно без участия какого-то АОП. Я уверен, что PostSharp может сделать хорошую работу, надеюсь, используя атрибуты, и в Code Contracts это будет просто:

Contract.Requires(qwerty != null);

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

(Если я когда-нибудь попробую подход PostSharp + Code Contracts, я обязательно напишу об этом, кстати ... Моно Сесил тоже может сделать это достаточно легко.)

РЕДАКТИРОВАТЬ: Чтобы расширить ответ Лорана, вы потенциально могли бы иметь:

new { qwerty }.CheckNotNull();

И если бы у вас было много параметров, не допускающих значения NULL, вы мог бы иметь:

new { qwerty, uiop, asdfg }.CheckNotNull();

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

РЕДАКТИРОВАТЬ: Код реализован, и сообщение в блоге должным образом сделанный. Крик, но весело

34
ответ дан 28 November 2019 в 05:23
поделиться

Одним словом: №

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

3
ответ дан 28 November 2019 в 05:23
поделиться

Я считаю, что проще всего сделать это с помощью фрагмента кода.

В вашем примере я могу ввести tna qwerty .

Вот фрагмент:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
    <CodeSnippet Format="1.0.0">
        <Header>
                <Title>Check for null arguments</Title>
                <Shortcut>tna</Shortcut>
                <Description>Code snippet for throw new ArgumentNullException</Description>
                <Author>SLaks</Author>
                <SnippetTypes>
                        <SnippetType>Expansion</SnippetType>
                        <SnippetType>SurroundsWith</SnippetType>
                </SnippetTypes>
        </Header>
        <Snippet>
                <Declarations>
                        <Literal>
                                <ID>Parameter</ID>
                                <ToolTip>Paremeter to check for null</ToolTip>
                                <Default>value</Default>
                        </Literal>
                </Declarations>
                <Code Language="csharp"><![CDATA[if ($Parameter$ == null) throw new ArgumentNullException("$Parameter$");
        $end$]]>
                </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>
2
ответ дан 28 November 2019 в 05:23
поделиться

См. Также ArgumentNullException и рефакторинг для полного решения по тем же принципам, что и ответ.

А как насчет:

public void Save(Category qwerty)
{   
   ThrowIfArgumentIsNull( () => return qwerty );
   qwerty.ThrowIfArgumentIsNull("qwerty");    
   // ....
}

затем определите ThrowIfArgumentIsNull как

public static void ThrowIfArgumentIsNull(Expression<Func<object>> test)
{
   if (test.Compile()() == null)
   {
      // take the expression apart to find the name of the argument
   }
}

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

1
ответ дан 28 November 2019 в 05:23
поделиться

Я бы порекомендовал вам сделать следующее:

public static void ThrowIfArgumentIsNull(this object value, string argument) 
{
    if (value == null)
    {
        throw new ArgumentNullException(argument);
    }
}

Использование дженериков в этом случае, похоже, не добавляет никакого значения. Но что касается вашего первоначального вопроса, я не думаю, что это возможно.

1
ответ дан 28 November 2019 в 05:23
поделиться

Мне нравится Применять из общих библиотек Lokad .

Базовый синтаксис:

Enforce.Arguments(() => controller, () => viewManager,() => workspace);

Это вызовет исключение с именем параметра и введите, если какой-либо из аргументов имеет значение NULL.

1
ответ дан 28 November 2019 в 05:23
поделиться