如何将列表中的字符串转换为“sbyte”等数字类型以键入sbyte?

时间:2018-03-31 21:21:52

标签: c# string methods types

我做了一个工作练习,但我的代码看起来不太好。我的代码中有很多WriteLine语句,我想创建一个方法。但是如何转换 - 例如 - 字符串“sbyte”来键入sbyte我不知道。

using System;
using static System.Console;

namespace Exercise02
{
    class Program
    {
        static void Main(string[] args)
        {

            string strFormat = "{0,-10} | {1,-4} | {2,30} | {3,30} |";

            HorizontalLIne();
            WriteLine(String.Format(strFormat, "Type", "Size", "Min", "Max"));
            HorizontalLIne();

            // I would like to write a method of this block of code
            WriteLine(String.Format(strFormat, "sbyte", sizeof(sbyte), sbyte.MinValue, sbyte.MaxValue));
            WriteLine(String.Format(strFormat, "byte", sizeof(byte), byte.MinValue, byte.MaxValue));
            WriteLine(String.Format(strFormat, "short", sizeof(short), short.MinValue, short.MaxValue));
            WriteLine(String.Format(strFormat, "ushort", sizeof(ushort), ushort.MinValue, ushort.MaxValue));
            WriteLine(String.Format(strFormat, "int", sizeof(int), int.MinValue, int.MaxValue));
            WriteLine(String.Format(strFormat, "uint", sizeof(uint), uint.MinValue, uint.MaxValue));
            WriteLine(String.Format(strFormat, "long", sizeof(long), long.MinValue, long.MaxValue));
            WriteLine(String.Format(strFormat, "ulong", sizeof(ulong), ulong.MinValue, ulong.MaxValue));
            WriteLine(String.Format(strFormat, "float", sizeof(float), float.MinValue, float.MaxValue));
            WriteLine(String.Format(strFormat, "double", sizeof(double), double.MinValue, double.MaxValue));
            WriteLine(String.Format(strFormat, "decimal", sizeof(decimal), decimal.MinValue, decimal.MaxValue));

            HorizontalLIne();

        }
        private static void HorizontalLIne()
        {
            WriteLine("-------------------------------------------------------------------------------------");
        }

    }

} 

我的计划是制作一个字符串列表,例如“sbyte”,“byte”“int”...并编写方法。
我尝试过以下方法:

string type = "sbyte";
private static void WriteLineOfType(string strFormat, string type) 
{
  Type typeFromString = Type.GetType(type);
  WriteLine(String.Format(strFormat,
          type,
          sizeof(typeFromString),
          typeFromString.MinValue,
          typeFromString.MaxValue));
}

但这种方法不起作用 我如何编写获取字符串的正确方法sbyte并写入控制台sizeof(sbyte)sbyte.MinValuesbyte.MaxValue

2 个答案:

答案 0 :(得分:0)

您遇到的问题是在.NET中,

  1. 原始数字类型没有实现公开其公共成员的公共接口,如+-MinValueMaxValue等。
    1. 静态成员不能是接口的一部分。这包括+等运算符以及MinValue等静态属性。
    2. 因此无法在数字类型上创建良好的抽象。这真的很不幸,但是如果在C#8或C#9(https://github.com/dotnet/csharplang/issues/164

      中添加了建议的形状特征,则可以解决这个问题。

      有可能与反射一起破解解决方案,但我会建议反对。它可能最终会成为您已有的更多代码,并且很难改变。

      您可能做的最好的事情就是封装一些字符串格式:

      string FormatValueRange<T>(T min, T max) 
         where T : struct
      {
           var type = typeof(T);
           return String.Format("{0,-10} | {1,-4} | {2,30} | {3,30} |", type.Name, sizeof(T), min, max);
      } 
      
      HorizontalLIne();
      WriteLine(String.Format(strFormat, "Type", "Size", "Min", "Max"));
      HorizontalLIne();   
      WriteLine(FormatValueRange<sbyte>(sbyte.MinValue, sbyte.MaxValue);
      WriteLine(FormatValueRange<short>(short.MinValue, short.MaxValue);
      WriteLine(FormatValueRange<int>(int.MinValue, int.MaxValue);
      //...
      HorizontalLIne();
      

答案 1 :(得分:0)

这是我的(部分)基于反射的解决方案。请注意,您不能将C#语言类型名称与Reflection一起使用,您必须使用它们对应的.Net框架名称。

void Main() {
    var typeNames = new[] { "sbyte", "byte", "int16", "uint16", "int32", "uint32", "int64", "uint64", "single", "double", "decimal" };

    foreach (var aTypeName in typeNames)
        WriteLineOfType(aTypeName);
}

// Define other methods and classes here
void WriteLineOfType(string aTypeName) {
    var typeFromString = Type.GetType($"System.{aTypeName}", false, true);
    if (typeFromString != null)
        Console.WriteLine(String.Format("{0,-10} | {1,-4} | {2,30} | {3,30} |",
                aTypeName,
                Marshal.SizeOf(Activator.CreateInstance(typeFromString)),
                typeFromString.GetField("MinValue").GetValue(typeFromString),
                typeFromString.GetField("MaxValue").GetValue(typeFromString)));
}