重写类field's ToString()方法

本文关键字:ToString 方法 field 重写 | 更新日期: 2023-09-27 18:16:23

我想知道,是否有办法覆盖byte[]类型的类字段的ToString()方法?我甚至不确定这是否可能……下面是示例代码:

public class Object
{
    private byte[] _content;
    public byte[] Content
    {
        get
        {
            return _content;
        }
        internal set
        {
            _content = value;
        }
    }
}

是否有可能重写Object.Content.ToString()方法的调用方式?

EDIT:为什么我需要它?我想Content可能是纯二进制数据,但它也可以是纯字符串。如果我需要文本表示,我打算使用Encoding.UT8.GetString(Object.Content),但是嘿!ToString()怎么样?它完全符合我的目标,也许我可以用它?

显而易见的方法是跳出我的头-在byte[]周围创建一个包装器并覆盖它的ToString(),但这对我来说看起来很丑,我认为不值得。

有什么优雅的方法来解决这个问题吗?还是绕开它?

提前感谢!

重写类field's ToString()方法

不,您不能覆盖或替换字节数组上的ToString()的实现,特别是Content属性。为了得到您想要的结果,您可能需要包装数组,而您已经声明不希望这样做。

您还可以在类中提供另一个属性,以有效地遮蔽Content属性,例如

public string ContentAsString
{
    get 
    {
        return /* custom string output of this.Content here */
    }
}

另一个选项是扩展字节数组(通过扩展方法),以提供字符串转换的自定义实现(通过不同的名称)(与上面相同的思想,表达方式不同)

static class MyExtensions
{
    public static string ToCustomString(this byte[] array)
    {
        return ...
    }
}
string result = obj.Content.ToCustomString();

这取决于上下文!如果这里的上下文是"在PropertyGrid或DataGridView中添加有意义的内容",那么您可能可以使用TypeConverter:

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new Form {Controls = {
            new PropertyGrid {SelectedObject = new SomeType
            {
                Content = new byte[] {0,1,2,3,4,5}                                               
            }, Dock = DockStyle.Fill}
        }});
    }
    public class SomeType
    {
        private byte[] _content;
        [TypeConverter(typeof(HexConverter))]
        public byte[] Content
        {
            get
            {
                return _content;
            }
            internal set
            {
                _content = value;
            }
        }
    }
    class HexConverter : TypeConverter
    {
        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
        {
            if(destinationType == typeof(string))
            {
                if (value == null) return "";
                byte[] raw = (byte[]) value;
                var sb = new StringBuilder(2*raw.Length);
                for (int i = 0; i < raw.Length; i++) sb.Append(raw[i].ToString("x2"));
                return sb.ToString();
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }
    }

正如@DanielHigarth所指出的,没有真正好的方法来做到这一点,我不确定为什么你想要…

但是,你可以:

使用postsharp等工具拦截程序集中对byte[].ToString()的所有调用,并返回任何您喜欢的结果,而不是实际结果。

使用扩展方法,例如

public static string ToElegantString(this byte[] bytes) {
{
  return "ElegantString";
}

如何代替重写。tostring()方法,只是修改get函数?

例如:

public string Content
{
    get
    {
        return YourByteFormatter(_content);
    }       
}

将字节数组定义为一个单独的class,这样您就可以给它一个ToString()覆盖。