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

В Mac OS X и Windows есть встроенные функции CompareAndSwap, которые вы должны использовать в любом случае (InterlockedCompareExchange () и OSAtomicCompareAndSwapPtrBarrier () соответственно). Таким образом, будет работать независимо от компиляторов на этих платформах.

В других Unix-системах это немного сложнее, если вы используете GCC 4.1 или новее, вы можете просто использовать его встроенную функцию __sync_val_compare_and_swap (), и многие, хотя и не все компиляторы Unix, поддерживают разумные расширения gcc, так как большая часть кода начинается в Linux предполагается, что они присутствуют.

Поэтому, если вы хотите обернуть их так, чтобы они работали практически со всеми компиляторами для всех процессоров в OS X и Windows, а также с GCC и некоторыми другими компиляторами на других платформах, вам следует сделать что-то вроде:

boolean CompareAndSwapPointer(volatile * void * ptr,
                                  void * new_value,
                                  void * old_value) {
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
  return OSAtomicCompareAndSwapPtr (old_value, new_value, ptr);
#elif defined(_MSC_VER)
  return InterlockedCompareExchange(ptr, new_value, old_value);
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
  return __sync_val_compare_and_swap(ptr, old_value, new_value);
#else
#  error No implementation
#endif
}

Это не проверено, но я думаю, что это должно быть правильно. Обратите внимание, как все библиотеки ОС принимают аргументы в разных порядках; -)

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

14
задан MrEdmundo 1 June 2009 в 14:10
поделиться

8 ответов

Вы можете сделать что-то вроде этого:

public static bool Compare<T>(string op, T x, T y) where T:IComparable
{
 switch(op)
 {
  case "==" : return x.CompareTo(y)==0;
  case "!=" : return x.CompareTo(y)!=0;
  case ">"  : return x.CompareTo(y)>0;
  case ">=" : return x.CompareTo(y)>=0;
  case "<"  : return x.CompareTo(y)<0;
  case "<=" : return x.CompareTo(y)<=0;
 }
}
13
ответ дан 1 December 2019 в 10:04
поделиться

РЕДАКТИРОВАТЬ

Как указал JaredPar, мое предложение ниже не сработает, поскольку вы не можете применять операторы к дженерикам ...

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

public int Compute (int param1, int param2, string op) 
{
    switch(op)
    {
        case "+": return param1 + param2;
        default: throw new NotImplementedException();
    }
}

public double Compute (double param1, double param2, string op) 
{
    switch(op)
    {
        case "+": return param1 + param2;
        default: throw new NotImplementedException();
    }
}

ORIG

Вы можете сделать что-то вроде этого.

Вам также нужно будет попробовать / поймать все это, чтобы убедиться, что любой T поддерживает конкретные операции.

Не возражайте, если я спрошу, зачем вам это нужно. Вы пишете какой-то математический анализатор?

public T Compute<T> (T param1, T param2, string op) where T : struct
{
    switch(op)
    {
        case "+":
            return param1 + param2;
        default:
             throw new NotImplementedException();
    }
}

public bool Compare<T> (T param1, T param2, string op) where T : struct
{
    switch (op)
    {
        case "==":
             return param1 == param2;
        default:
             throw new NotImplementedException();
    }
}
5
ответ дан 1 December 2019 в 10:04
поделиться

Нет, это невозможно, и какого черта вы хотите это сделать?

Вы могли бы , конечно, создайте такую ​​функцию, как:

 public static bool Compare<T>(char op, T a, T b);
4
ответ дан 1 December 2019 в 10:04
поделиться

Вам следует изучить использование деревьев выражений .NET 3.5. Вы можете вручную создавать выражения в дереве выражений (в основном в AST), а затем вызывать Expression.Compile () для создания вызываемого делегата. Вашему методу LogicRule.Test () потребуется построить дерево выражений, заключить дерево в выражение LambdaExpression, которое принимает объект, к которому вы применяете правила, в качестве аргумента, вызывает Compile () и вызывает полученный делегат.

3
ответ дан 1 December 2019 в 10:04
поделиться

Я сделал что-то подобное с помощью:

http://flee.codeplex.com/

Этот инструмент может по существу вычислять широкий диапазон выражений. Базовое использование будет заключаться в передаче строки вроде '3> 4', и инструмент вернет false.

Однако вы также можете создать экземпляр оценщика и передать пары имя / значение объекта, и это может быть немного более интуитивно понятный IE: myObject ^ 7

На сайте codeplex есть еще тонна дополнительных функций.

2
ответ дан 1 December 2019 в 10:04
поделиться
<Function = "PredicateMore" Param1 = "Object1.Value" Param2 = "0"/>
0
ответ дан 1 December 2019 в 10:04
поделиться

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

   public static implicit operator Operator(string op) 
   {
      switch(op) {  
         case "==" : 
            return new EqualOperator();
            ...
      }
   }

   Operator op = "<";
   if( op.Compare(x,y) ) { ... }
   //or whatever use syntax you want for Operator.
0
ответ дан 1 December 2019 в 10:04
поделиться

Vici Parser (с открытым исходным кодом), возможно, вам поможет. Это синтаксический анализатор выражений C #, в котором вы можете просто передать строку, содержащую выражение, и получить обратно вычисленный результат.

0
ответ дан 1 December 2019 в 10:04
поделиться
Другие вопросы по тегам:

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