【问题标题】:How to convert string from list to type of numbers like "sbyte" to type sbyte?如何将字符串从列表转换为“sbyte”等数字类型以键入sbyte?
【发布时间】:2018-09-10 13:32:16
【问题描述】:

我做了一个工作练习,但我的代码看起来不太好。我的代码中有很多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

【问题讨论】:

    标签: c# string methods types


    【解决方案1】:

    您面临的问题是在 .NET 中,

    1. 原始数值类型不实现公开其公共成员的公共接口,例如 +-MinValueMaxValue 等。

    1. 静态成员不能是接口的一部分。这包括像 + 这样的运算符以及像 MinValue 这样的静态属性。

    因此,没有办法对数字类型创建良好的抽象。这真的很不幸,但如果在 C#8 或 C#9 中添加建议的 Shapes 功能可能会得到解决 (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();
    

    【讨论】:

      【解决方案2】:

      这是我的(部分)基于反射的解决方案。请注意,您不能将 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)));
      }
      

      【讨论】:

        猜你喜欢
        • 2015-08-21
        • 2011-08-05
        • 1970-01-01
        • 2014-06-25
        • 2015-03-09
        • 2018-10-28
        • 2011-03-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多