【问题标题】:Most efficient way to handle different primitive types处理不同原始类型的最有效方法
【发布时间】:2019-03-20 17:47:38
【问题描述】:

我正在制作一个游戏,其中包括允许玩家选择不同的选项和操作,然后执行它们以获得真假(然后根据结果做其他事情)。

我(作为程序员)最终得到的是两个对象和一个以某种方式比较它们的请求。

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;
}

编辑:

感谢大家的回答和cmets。

对于任何想知道的人。这是我提出的测试程序,基于 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...

【问题讨论】:

  • 什么是 compare0 和 compare1? arg0和arg1转换后的结果?
  • Convert、IComparable 和 Equals 很可能会在这里有所帮助。
  • compar0 和 compare 1 将是要比较的两个变量。 string、int、float 等 arg0 和 arg1 基本上都是

标签: c# types type-conversion comparison


【解决方案1】:

【讨论】:

    【解决方案2】:

    您可以使用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
    

    等等……

    【讨论】:

    • 为什么在使用 Equals 和 NotEquals 时将 args 转换为字符串?使用Left.CompareTo(Right)==0
    • 我喜欢,除了一件事:只会抛出 exc 而不是默认返回 false
    • Tim Schmelter:在这个问题中,D3Duck 想要:“默认情况下,不可比较的类型会转换为字符串,然后进行比较”。
    • Vladi Pavelka:很好地发现,编辑默认抛出异常。
    • 这并不能真正回答为什么您在前两个中使用 ToString.Equals() 而在后两个中使用 .Compare 的问题。
    【解决方案3】:

    如果您只考虑原始数据类型(不包括字符串,因为它们是非原始的),那么您总是可以将 compare0 和 compare1 转换为 double 然后进行比较。

    类似这样的:

    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;
    }
    

    但是如果您需要包含字符串,那么我认为您应该单独处理它们。无论如何,您只能对字符串执行 == 或 !=。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-25
      • 2022-10-09
      • 2019-04-06
      • 2012-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多