Как я могу получить любое выражение в C # в виде строки? - PullRequest
1 голос
/ 23 августа 2011

Во многих случаях требуется имя выражения, параметра, оператора и т. Д. Например:

public abstract void Log(string methodName, string parameterName, string message);

public void FooMethod(string value)
{
    if (value == null)
    {
        this.Log("FooMethod", "value", "The value must be whatever...");
        throw new ArgumentNullException("value");
    }

    if (value.Length < 5)
    {
        this.Log("FooMethod", "value.Length", "The value length must be whatever...");
        throw new ArgumentException("value");
    }
}

Есть ли способ автоматически получить эти строковые литералы, например, с помощью ключевого слова, которое можетиспользоваться как typeof(string)?Или есть простой и эффективный подход, основанный на рефлексии?

Я не ищу способ проверить и зарегистрировать этот параметр (который на самом деле является только примером).Я ищу метод для получения части кода как string.

Следующее будет более точным, может быть проверено компилятором и также будет учитываться при рефакторинге кода:

public void FooMethod(string value)
{
    if (value == null)
    {
        this.Log(literal(this.FooMethod), literal(value), "The parameter '" + literal(value) + "' must be whatever...");
        throw new ArgumentNullException(literal(value));            
    }

    if (value.Length < 5)
    {
        this.Log(literal(this.FooMethod), literal(value.Length), "The value length must be whatever...");
        throw new ArgumentException(literal(value));
    }
}

Ответы [ 3 ]

2 голосов
/ 23 августа 2011

Вы можете создавать такие статические методы для всех возможных типов. Ниже приведено название метода.

public static string GetString(Action obj)
{
    return obj.Method.Name;
}

public static string GetString(Delegate obj )
{
    return obj.Method.Name;
}
1 голос
/ 23 августа 2011

Звучит так, как вам нужно StackTrace.GetFrame . Этот метод даст вам необходимый объект StackFrame, из которого вы можете найти эту информацию.

Проверьте следующий пример кода

StackFrame fr = new StackFrame(1,true);
StackTrace st = new StackTrace(fr);
this.Log.WriteEntry(fr.GetMethod().Name,
                    fr.GetMethod().GetParameters()[0].Name,
                    "The value must be whatever...");

Кстати, во втором примере кода вызовы метода Log никогда не будут выполняться, потому что перед вызовами выдается исключение. Ни один код в методе не будет выполнен после возникновения исключения, за исключением кода в блоке finally. См. эту статью .

0 голосов
/ 23 августа 2011

Это зависит от вашей цели.Если вы хотите получить значения времени выполнения Martin Doms , ответ может быть решением.Если вы хотите иметь возможность связать скажем ArgumentNullException с конкретным именем аргумента и убедиться, что если вы измените имя, которое вы можете использовать рефакторинг, вы можете сделать что-то вроде этого:

 public static void NotNull<T>(Expression<Func<IEnumerable<T>>> exp)
        {
            var expBody = exp.Body as MemberExpression;
                T value = exp.Compile().Invoke();
                if (value == null){
                    string memberName;
                    if (expBody != null){
                        memberName = expBody.Member.Name;
                    } else{
                        memberName = "member";
                    }
                    throw new ArgumentNullException(memberName, memberName + " cannot be null");
                }
        }

, тогда вы можете использовать его следующим образомпоэтому:

public void Method(string value){
  Ensure.NotNull(()=>value);
}

он проверит, имеет ли значение значение NULL, и отформатирует соответствующее сообщение в ArgumentNullException, если значение NULL.Как бы то ни было, если вы используете .NET 4.0, я бы предложил вместо этого использовать контракты для этого.Не то чтобы это на самом деле решает ваши конкретные потребности, но проверка аргументов с использованием контрактов имеет много преимуществ, когда дело доходит до документации и статического анализа, по сравнению с тем, как это делается «старомодным способом»

...