如何制作一个带前缀的字符串类?

时间:2018-01-31 07:06:23

标签: c# string

我需要一类string个对象来处理十六进制字符串。它应该完全string一样,但非常string 小写前缀 "0x"

像这样的东西

class PString :String
{
      // some magic here
}

PString s0 = "aaaAa";

s0.ToString();  //should be "0xaaaaa";

5 个答案:

答案 0 :(得分:4)

您可以简单地将值存储为整数,而不是为此构建自定义类。然后,当您需要将其显示为十六进制时,请使用.toString() standard numeric formatting

int myInt = 100;
string myHexString = myInt .ToString("X");

答案 1 :(得分:3)

您可以使用隐式转换来执行此操作:

public class PString
{
    private string data;
    public static implicit operator string(PString value) => value.ToString();
    public static implicit operator PString(string value) => new PString(value);

    public PString(string value) => data = value;
    public override string ToString() => $"0x{data.ToLower()}";
}

在行动HERE中查看 如果它应该仅限于或仅检查有效字符,则可以与@DimitryBychenko的解决方案结合使用,如:

public class PString
{
    private string data;
    public static implicit operator string(PString str) => str.ToString();
    public static implicit operator PString(string str) => new PString(str);

    public PString(string value)
    {
        if (value?.Any(c => !(c >= '0' && c <= '9' || 
                      c >= 'a' && c <= 'f' || 
                      c >= 'A' && c <= 'F')) == true)
        {
            throw new ArgumentException("Incorrect value format", "value")
        }
        data = value;  
    }
    public override string ToString()
        => String.IsNullOrWhiteSpace(data) ? String.Empty : $"0x{data.ToLower()}";
}

答案 2 :(得分:3)

我建议对现有的String类使用(扩展名)方法,而不是自定义:if

  

它的行为完全string

然后该课程为string

 public static partial class StringExtensions {
   public static string ToStringHex(this string value) {
     if (null == value)
       return null; // Or throw ArgumentNullException

     if (string.IsNullOrEmpty(value))
       return "";   // Or throw ArgumentException

     // Let's be nice and let 0x... strings
     if (value.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
       value = value.Substring(2);

     if (value.All(c => c >= '0' && c <= '9' || 
                        c >= 'a' && c <= 'f' || 
                        c >= 'A' && c <= 'F')) 
       return $"0x{value.ToLowerInvariant()}";

     throw new ArgumentException("Incorrect value format", "value"); 
   }
 }

...

 String s0 = "aaaAa"; 

 String result = s0.ToStringHex();    

答案 3 :(得分:2)

唉,System.String是密封的,所以你不能继承它 但是,您可以为其添加扩展方法:

public static string AddHexPrefix(this string str)
{
    return "0x" + str;
}

或者创建一个将字符串保存在其中的类,并为其添加一个隐式运算符:

public class HexString 
{
    private string _string;

    public HexString(string str)
    {
        _string = str;
    }

    public override string ToString()
    {
        return "0x" + _string;
    }

    public static implicit operator HexString(string str)
    {
        return new HexString(str);
    }
}

当然,这并不能确保你得到的字符串实际上是一个十六进制值 - 目前,没有什么能阻止你做这样的事情:

HexString s = "Zohar";

要做到这一点,你应该检查你在构造函数中得到的字符串是否只包含0-9和a-f,如果没有则抛出异常。
所以你的课可能看起来像这样:

private static Regex validator = new Regex(@"^[a-zA-Z0-9]*$"); // no need to create it over and over again in the constructor

public HexString(string str)
{
    if(!validator.IsMatch(str))
        throw new FormatException("The string was not recognized as a valid hexa-decimal value");
    _string = str;
}

话虽如此,我必须同意Soviut - 您应该只使用int来存储值并使用ToString("x")将其转换为十六进制。

答案 4 :(得分:1)

在你的课上写:

public override string ToString()
{
     return "0x" + s0.ToLower();
}

字符串类是密封的,您无法继承它。在这种情况下应该编写自己的类,方法返回这样的值。与=> "0x" + s0.value.ToLower()

一样