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

Мне удалось решить эту проблему с помощью этого вызова

Properties props = PropertiesUtil.loadProperties("whatever.properties");

Extra, вы должны поместить свой файл whatever.properties в / src / main / resources

1
задан Mattia Caruso 11 March 2019 в 15:02
поделиться

1 ответ

Чтобы убедиться, что я понимаю, что вы пытаетесь сделать, если метод имеет атрибут ExecuteMe, вы хотите вызвать метод, передавая аргументы из атрибута в метод?

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

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

Вам нужно получить свойство args из атрибута и передать эти значения при вызове метода.

Просто для иллюстрации я собираюсь использовать метод, в котором подписи совпадают.

public class ClassWithMethod
{
    [ExecuteMe("hello", "reflection")]
    public void M3(params object[] args)
    {
        var strings = args.Where(arg => arg != null).Select(arg => arg.ToString());
        Console.WriteLine(string.Join(", ", strings));
    }

    // Just to verify that we're only invoking methods with the attribute.
    public void MethodWithoutAttribute() { }
}

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

Я переставил несколько вещей, но вы увидите, что происходит:

static void Main(string[] args)
{
    var assembly = Assembly.GetExecutingAssembly();

    foreach (var type in assembly.GetTypes())
    {
        var methodInfos = type.GetMethods();

        // looking at all the methods, not yet narrowing it down to those
        // with the attribute.
        foreach (var mInfo in methodInfos)
        {
            // We don't just want to know if it has the attribute.
            // We need to get the attribute.
            var executeMeParameter = mInfo.GetCustomAttribute<ExecuteMe>();

            // If it's null the method doesn't have the attribute. 
            // Ignore this method.
            if (executeMeParameter == null) continue;

            // We don't need to create the instance until we know that we're going
            // to invoke the method.
            object act = Activator.CreateInstance(type);

            // Pass the args property of the attribute (an array of objects)
            // as the argument list for the method.
            mInfo.Invoke(act, new object[]{executeMeParameter.args});
        }

        if (type.IsClass)
            Console.WriteLine(type.FullName);
    }
    Console.ReadLine();
}

В этом случае мы просто передаем все аргументы из атрибута. Это та часть, где немного грязно. Что если у args было три строковых значения, но у метода был один параметр int?

Эта часть немного странная. Я должен был сделать это из-за ключевого слова params.

mInfo.Invoke(act, new object[]{executeMeParameter.args});
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

[ExecuteMe]
public void CallM3()
{
    M3("Hello", "reflection");
}

public void M3(params object[] args)
{
    var strings = args.Where(arg => arg != null).Select(arg => arg.ToString());
    Console.WriteLine(string.Join(", ", strings));
}

... и у атрибута нет аргументов:

public class ExecuteMe : Attribute
{
}

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

0
ответ дан Scott Hannen 11 March 2019 в 15:02
поделиться
Другие вопросы по тегам:

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