Итерация по параметрам метода для проверки - PullRequest
8 голосов
/ 01 октября 2009

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

Ответы [ 8 ]

15 голосов
/ 01 октября 2009

Ну, нет, если не считать:

public void Foo(string x, object y, Stream z, int a)
{
    CheckNotNull(x, y, z);
    ...
}

public static void CheckNotNull(params object[] values)
{
    foreach (object x in values)
    {
        if (x == null)
        {
            throw new ArgumentNullException();
        }
    }
}

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

public static void CheckNotNull(object x, object y)
{
    if (x == null || y == null)
    {
        throw new ArgumentNullException();
    }
}

// etc

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

public void Foo([NotNull] string x, [NotNull] object y, 
                [NotNull] Stream z, int a)
{
    // PostSharp would inject the code here.
}

По общему признанию я вероятно хотел бы, чтобы PostSharp преобразовал это в Кодовые контракты вызовы, но я не знаю, насколько хорошо они играют вместе. Может быть один день, когда мы сможем написать Spec #-like:

public void Foo(string! x, object! y, Stream! z, int a)
{
    // Compiler would generate Code Contracts calls here
}

... но не в ближайшее время :)

2 голосов
/ 01 октября 2009

Вы можете определить параметр метода с ключевым словом params. Это позволит передать в метод метод с переменной длиной числа параметров. Затем вы можете перебирать их и проверять наличие нулевых ссылок или чего-либо еще с ним.

public void MyMethod(params object[] parameters) {
     foreach (var p in parameters) {
         ...
     }
}

// method call:
this.MyMethod("foo", "bar", 123, null, new MyClass());

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

1 голос
/ 01 октября 2009

Некоторое время назад у меня был тот же вопрос, но я хотел сделать это для целей ведения журнала. Я никогда не находил хорошего решения, но нашел эту ссылку, касающуюся использования подхода, основанного на AOP, для регистрации записей метода и выхода. Суть его заключается в том, чтобы использовать среду, которая может читать ваш класс и вставлять код во время выполнения, чтобы делать то, что вы пытаетесь делать. Звучит не просто.

Как перехватить вызов метода в C #?

0 голосов
/ 09 мая 2017
var mandatoryFields = (new object[] { input1, input2 }).Where(v => v == null || v.ToString().Trim() == "");

Вы получите список нулевых параметров.

Итак, вы можете просто добавить

if(mandatoryFields.ToArray().Count > 0){}
0 голосов
/ 01 октября 2009

После предоставления тривиального примера метода, использующего ключевое слово params, RaYell говорит:

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

Я бы, конечно, согласился, что объявление метода, который принимает два strings, один int, object, который может быть нулевым, и другой объект MyClass, использующий params, является плохой идеей. Тем не менее, являются (на мой взгляд) совершенно правильными и подходящими приложениями ключевого слова params, а именно, когда все параметры имеют одинаковый тип. Например:

public T Max<T>(T x, T y) where T : IComparable<T> {
    return x.CompareTo(y) > 0 ? x : y;
}

public T Max<T>(params T[] values) where T : IComparable<T> {
    T maxValue = values[0];

    for (int i = 1; i < values.Length; i++) {
        maxValue = Max<T>(maxValue, values[i]);
    }

    return maxValue;
}
0 голосов
/ 01 октября 2009

Вы вполне могли бы автоматизировать проверку параметров с помощью библиотеки AOP , такой как PostSharp .

0 голосов
/ 01 октября 2009

Вы можете посмотреть Блок приложения проверки , который можно рассматривать как пример автоматической проверки, и Блок приложения Unity (в частности, его функцию перехвата) в отношении перехвата вызовов. и проверка параметров.

0 голосов
/ 01 октября 2009

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

Возможно, вы могли бы использовать Postsharp и создать аспект, в котором вы выполняете эту проверку. Затем, во время компиляции, Postsharp может «соткать» аспект (добавить дополнительный код) для каждого написанного вами метода ...

...