Самый эффективный способ обработки различных примитивных типов - PullRequest
0 голосов
/ 16 октября 2018

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

Что я в итоге получаюwith (как программист) - это два объекта и запрос на их сравнение определенным образом.

public object arg0;
public CompareType compareType;
public object arg1;

Аргументы могут быть int, float, string или bool,Представьте, что CompareType представляет собой такие параметры, как GREATER_THAN, EQUALS, LESS_OR_EQUAL_THAN и т. Д. По умолчанию несопоставимые типы преобразуются в string, а затем сравниваются (и, вероятно, получаются ложными).

Я не смог придумать правильный способ их решения, чтобы получить true или false в конце сравнения, без написания КАЖДОЙ единственной возможности.

Есть ли более общий способпреобразовать типы в «наиболее похожий», кроме приведения и явных преобразований?

После этого это будет просто переключатель на основе CompareType.

switch(compareType)
{ 
    case CompareTypes.EQUALS:
        return compare0 == compare1;

    case CompareTypes.GREATER_THAN: 
        return compare0 > compare1;

    case CompareTypes.LESS_OR_EQUAL_THAN: 
        return compare0 <= compare1;

    // etc.

    default:
        return false;
}

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

Спасибо всем за ответы и комментарии.

Для тех, кто хочет знать. Это тестовая программа, которую я придумал, основываясь на 99% на лучший ответ (пришлосьизмените его немного, чтобы он работал в онлайн-компиляторе):

using System;

public class Program
{
    public static void Main()
    {
        WriteResult("1", CompareType.Equals, 1);
        WriteResult(5, CompareType.Equals, 1);
        WriteResult("2", CompareType.Equals, 1);
        WriteResult("2", CompareType.GreaterThan, 1);
        WriteResult("2", CompareType.LessThan, 1);
        WriteResult(2, CompareType.GreaterThan, "1");
        WriteResult(2, CompareType.LessThan, "1");
        WriteResult("1", CompareType.Equals, "2");
        WriteResult(1, CompareType.Equals, 1.0f);
        WriteResult(1, CompareType.LessThan, 2.0f);
    }

    public static void WriteResult(IComparable left, CompareType compareType, IComparable right)
    {
        Comparison comparison = new Comparison(left, compareType, right);

        Console.WriteLine(left.GetType() + " " + left.ToString() + " - " + 
                          compareType.ToString() + " - " + 
                          right.GetType() + " " + right.ToString() + " = " + 
                          comparison.Excecute().ToString());
    }

    public class Comparison
    {
        public IComparable Left { get; set; }
        public CompareType CompareType { get; set; }
        public IComparable Right { get; set; }

        public Comparison(IComparable left, CompareType compareType, IComparable right) 
        {
            Left = left;
            CompareType = compareType;
            Right = right;
        }

        public bool Excecute()
        {
            switch (CompareType)
            {
                case CompareType.Equals:
                    return IsTypeMatch(Left, Right) ? Left.CompareTo(Right) == 0 : Left.ToString().Equals(Right.ToString());
                case CompareType.NotEquals:
                    return IsTypeMatch(Left, Right) ? Left.CompareTo(Right) != 0 : !Left.ToString().Equals(Right.ToString());
                case CompareType.GreaterThan:
                    return IsTypeMatch(Left, Right) ? Left.CompareTo(Right) != 0 : Left.ToString().CompareTo(Right.ToString()) > 0;
                case CompareType.LessThan:
                    return IsTypeMatch(Left, Right) ? Left.CompareTo(Right) != 0 : Left.ToString().CompareTo(Right.ToString()) < 0;
                default:
                    throw new NotImplementedException();
            }
        }

        //private bool IsTypeMatch => Left.GetType().Equals(Right.GetType());

        private bool IsTypeMatch(IComparable Left, IComparable Right) 
        {
            return Left.GetType().Equals(Right.GetType());
        }
    }
}

public enum CompareType
{
    Equals = 1,
    NotEquals = 2,
    GreaterThan = 3,
    LessThan = 4,
}

РЕЗУЛЬТАТ:

System.String 1 - Equals      - System.Int32  1 = True
System.Int32  5 - Equals      - System.Int32  1 = False
System.String 2 - Equals      - System.Int32  1 = False
System.String 2 - GreaterThan - System.Int32  1 = True
System.String 2 - LessThan    - System.Int32  1 = False
System.Int32  2 - GreaterThan - System.String 1 = True
System.Int32  2 - LessThan    - System.String 1 = False
System.String 1 - Equals      - System.String 2 = False
System.Int32  1 - Equals      - System.Single 1 = True
System.Int32  1 - LessThan    - System.Single 2 = True

Я, честно говоря, не уверен, насколько string "2" больше string "1", но это, наверное, я не знаю, как сравниваются строки.Выкл в MSDN ...

Ответы [ 3 ]

0 голосов
/ 16 октября 2018

В качестве параметра можно использовать интерфейс IComparable .

Пример:

public class Comparison
{
    public IComparable Left { get; }
    public CompareType CompareType { get; }
    public IComparable Right { get; }

    public Comparison(IComparable left, CompareType compareType, IComparable right) 
    {
        Left = left;
        CompareType = compareType;
        Right = right;
    }

    public bool Excecute()
    {
        switch (CompareType)
        {
            case CompareType.Equals:
                return IsTypeMatch ? Left.CompareTo(Right) == 0 : Left.ToString().Equals(Right.ToString());
            case CompareType.NotEquals:
                return IsTypeMatch ? Left.CompareTo(Right) != 0 : !Left.ToString().Equals(Right.ToString());
            case CompareType.GreaterThan:
                return IsTypeMatch ? Left.CompareTo(Right) != 0 : Left.ToString().CompareTo(Right.ToString()) > 0;
            case CompareType.LessThan:
                return IsTypeMatch ? Left.CompareTo(Right) != 0 : Left.ToString().CompareTo(Right.ToString()) < 0;
            default:
                throw new NotImplementedException();
        }
    }

    private bool IsTypeMatch => Left.GetType().Equals(Right.GetType());
}

public enum CompareType
{
    Equals = 1,
    NotEquals = 2,
    GreaterThan = 3,
    LessThan = 4,
}

Это можно назвать как:

new Comparison("1", CompareType.Equals, 1).Excecute(); // returns true

и

new Comparison(2, CompareType.GreaterThan, 1).Excecute(); // returns true

и т.д ...

0 голосов
/ 16 октября 2018

Если вы рассматриваете только примитивные типы данных (которые исключают строки, поскольку они не являются примитивными), то вы всегда можете привести к приведению сравнить0 и сравнить1 с удвоением, а затем выполнить сравнение.

примерно так:

switch(compareType)
{ 
case CompareTypes.EQUALS:
    return (double)compare0 == (double)compare1;

case CompareTypes.GREATER_THAN: 
    return (double)compare0 > (double)compare1;

case CompareTypes.LESS_OR_EQUAL_THAN: 
    return (double)compare0 <= (double)compare1;
// etc.
default:
    return false;
}

Но если вам нужно включить строки, то я считаю, что вы должны обрабатывать их отдельно.В любом случае вы можете делать только == или! = Со строками.

0 голосов
/ 16 октября 2018
...