Чтобы убедиться, что я понимаю, что вы пытаетесь сделать, если метод имеет атрибут 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
{
}
Разница в том, что все сильно набрал и компилирует. Вам не нужно беспокоиться о том, будут ли параметры совпадать во время выполнения.
Вы не можете создайте индекс для представления, которое использует оператор объединения. На самом деле никакого пути к этому нет, извините!
Я мог бы представить, что вы видели это, но посмотрите эту страницу MSDN . В нем приводятся требования к индексированным представлениям и объясняется, что они из себя представляют и как они работают.
Относительно того, увидите ли вы выигрыш в производительности, если МОЖЕТЕ индексировать представление, это будет полностью зависеть от размера ваших таблиц. Я бы не ожидал какого-либо влияния на создание отдельных индексированных представлений, поскольку предположил бы, что ваши таблицы уже проиндексированы, и вы не выполняете никаких соединений или логики в представлении.
Почему в МИРЕ вы используете UNION?
С литералами в SQL существует НУЛЬ шансов, что Буду иметь дубликаты. Итак, еще раз, зачем использовать UNION?
UNION заставляет возникать отдельное событие, и оно немного медленнее, чем DISTINCT.
Но так как у вас есть что-то похожее на это:
SELECT 'A'
UNION
SELECT 'B'
UNION
SELECT 'C'
Нет никакой возможности, что у вас когда-либо будут дубликаты.
Измените его на UNION ALL, и ваш запрос будет выполняться намного быстрее.
Это фундаментальный SQL - написание хорошо настроенного запроса важнее, чем создание индексов представления. Начните с основ, разберитесь с SQL, настройте ваш запрос, ЗАТЕМ беспокойтесь о расходе места и замедлении DML для повышения скорости запросов.
Литералы в запросе предотвращают дублирование между таблицами. Единственная оставшаяся возможность - дупс в таблице (ах). Поскольку столбцы выглядят как PK, и нет никаких объединений, которые могли бы вызвать дублирование, и поскольку все таблицы выглядят как справочные таблицы, то, что я сказал, правильно. Если это предположение неверно, вы можете законно использовать UNION без ALL. Однако я считаю, что в 99% случаев люди действительно хотели использовать ALL, и в нашей компании принято добавлять комментарии к SQL только с помощью UNION, потому что это часто ошибка. т.е. UNION - да, мне нужен отдельный список.
В нашей компании принято добавлять комментарий к SQL только с UNION, потому что это часто ошибка. т.е. UNION - да, мне нужен отдельный список. В нашей компании принято добавлять комментарий к SQL только с UNION, потому что это часто ошибка. т.е. UNION - да, мне нужен отдельный список.