重写类字段的ToString()方法

5

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

public class Object
{
    private byte[] _content;

    public byte[] Content
    {
        get
        {
            return _content;
        }

        internal set
        {
            _content = value;
        }
    }
}

是否有可能覆盖调用Object.Content.ToString()方法的方式?
编辑:为什么需要这样做?我想Content可能是纯二进制数据,但它也可以是纯字符串。如果我需要文本表示,我计划使用Encoding.UT8.GetString(Object.Content),但是嘿!ToString()完全符合我的目标,也许我可以以某种方式使用它?
显而易见的方法浮现在我的脑海中——创建一个byte[]的包装器并覆盖其ToString(),但这对我来说看起来很丑陋,我认为不值得这样做。
有没有优雅的方法来解决这个问题?或者绕过它?
非常感谢!

5
没其他办法。但是,你真的为什么想那样做呢? - Daniel Hilgarth
那么这不会对其他byte[]对象造成问题吗?也许你可以通过在"Object"类中扩展一个返回所需ToString()功能的方法或属性来解决问题? - Stefan
1
你不能这样做,但是你可以在你的类中重写ToString()方法,以便输出是你的字节数组所需的字符串表示形式,然后你可以使用Object.ToString()。我相信这只是一个愚蠢的例子,但请不要创建一个名为Object的类。 - Ben Robinson
@vanhelgen,注意扩展方法不能与对象的成员方法同名。重载决议始终会选择成员方法作为更好的匹配项而非扩展方法。 - Anthony Pegram
3
顺便说一下,永远不要将某个东西命名为“Object”;p - Marc Gravell
显示剩余3条评论
5个回答

5
不,您不能覆盖或替换字节数组的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();

我喜欢使用扩展的想法。我会尝试一下。谢谢! - shytikov

3
这取决于上下文!如果上下文是“在属性网格或数据网格中显示有意义的内容”,那么您可能可以使用类型转换器:
    [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);
        }
    }

1
正如@DanielHigarth所指出的那样,没有真正好的方法来做到这一点,我不确定为什么你想要这样做...但是,你可以:
使用像postsharp这样的工具来拦截你程序集中所有对byte[].ToString()的调用,并返回你想要的任何东西,而不是实际结果。
使用扩展方法,例如:
public static string ToElegantString(this byte[] bytes) {
{
  return "ElegantString";
}

这种方法有什么缺点吗?我问这个是因为这很接近我想要的。 - shytikov

0
将您的字节数组定义为一个独立的类,这样您就可以给它一个ToString()重写。

0

不妨不要覆盖 .ToString() 方法,而是修改 get 函数呢?

例如:

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

我需要在运行时动态地在“byte[]”和“string”表示之间进行切换。 - shytikov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接