Можно ли вызывать операторы типа значения через отражение? - PullRequest
13 голосов
/ 09 августа 2009

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

Ответы [ 5 ]

9 голосов
/ 19 апреля 2012

А как же это просто, мало и работает :) 1001 *

public T Add<T>(object x, object y)
{
    return (T)Convert.ChangeType((dynamic)x + (dynamic)y, typeof(T));
}
7 голосов
/ 09 августа 2009

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

4 голосов
/ 09 августа 2009

Что именно вы хотите сделать? Работа с различными значениями операторов (примитив (сопоставленный с определенными инструкциями 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()();
0 голосов
/ 09 августа 2009

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

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

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

0 голосов
/ 09 августа 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...