Можно ли вызывать операции типа значения через отражение?

Как операторы С#, например. +, + =, == являются переопределяемыми. Это позволяет мне думать, что это своего рода методы, поэтому задайтесь вопросом, есть ли способ называть их, используя отражение, например, на Int32.

Ответы

Ответ 1

Да, пользовательские операторы invokable с использованием отражения (у них есть специальные имена, такие как op_Addition), но System.Int32 не определяет их, поскольку основные встроенные типы обрабатываются непосредственно с помощью кодов IL, таких как add, а не вызовы методов.

Ответ 2

Что ж, это просто, мало и работает:)

public T Add<T>(object x, object y)
{
    return (T)Convert.ChangeType((dynamic)x + (dynamic)y, typeof(T));
}

Ответ 3

Что именно вы хотите сделать? Работа с различными значениями операторов (примитивные (сопоставленные с конкретными инструкциями IL), пользовательские (сопоставленные со статическими методами) и снятые (предоставляемые в виде шаблона компилятором) делают это болезненным. Если вы просто хотите использовать операторы, тогда можно написать код, который обеспечивает поддержку оператора через generics. У меня есть код для этого, который свободно доступен в MiscUtil (описание и примеры).


Как нетипизированный пример (обратите внимание, что это не очень эффективно, но работает):

object x = 123, y = 345; // now forget that we know that these are ints...
object result = Expression.Lambda<Func<object>>(
    Expression.Convert(Expression.Add(
        Expression.Constant(x), Expression.Constant(y)),
    typeof(object))).Compile()();

Ответ 4

Было бы очень неэффективно, если бы добавление или сравнение двух целых чисел требовало вызова метода, поэтому эти простые операции над фундаментальными типами генерируются кодом, как объяснено в другом ответе, и не могут быть вызваны с помощью отражения. Один интересный встроенный тип значения decimal (или System.Decimal). Этот struct поддерживает литеральные значения в С#, но ведет себя как реальный тип значения и предоставляет множество операторов, которые могут быть вызваны посредством отражения.

Если вам интересно, вы можете использовать Reflector, чтобы просмотреть всех участников, открытых с помощью System.Int32.

Ответ 5

Здесь есть хорошие ответы, поэтому просто добавьте еще что-то не упомянутое:

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

Одна хорошая вещь, чтобы попробовать, - попытаться использовать дерево выражений. Здесь небольшой образец. Конечно, производительность не слишком приятная, но мы все равно знаем, что мы получаем с Reflection.