简体   繁体   中英

Override class field's ToString() method

I'm wondering, is there any way to override ToString() method of the class field with type byte[] ? I'm even not sure it's possible... Here is the sample code:

public class Object
{
    private byte[] _content;

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

        internal set
        {
            _content = value;
        }
    }
}

Is it possible to override the way how Object.Content.ToString() method is called?

EDIT : Why do I need it? I suppose that Content might be pure binary data, however it can be pure string too. I panned to use Encoding.UT8.GetString(Object.Content) in case if I will need text representation, but hey! what about ToString() it fits my goals perfectly, maybe I can use it somehow?

The obvious method is popping out my head — create a wrapper around byte[] and override its ToString() but this looks ugly for me and I don't think it worth it.

Is there any elegant way to solve this issue? Or work around it?

Many thanks in advance!

No, you cannot override or replace the implementation of ToString() on the byte array generally or the Content property specifically. To get your desired outcome, you could need to wrap the array, which you've stated you do not want to do.

You could also provide another property inside the class to effectively shadow the Content property, such as

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

One other option is to extend the byte array (via an extension method) to provide a custom implementation of a string conversion (and by a different name) (same idea as above, expressed differently)

static class MyExtensions
{
    public static string ToCustomString(this byte[] array)
    {
        return ...
    }
}

string result = obj.Content.ToCustomString();

It depends on the context! If the context here is "to dipslay something meaningful in a PropertyGrid or DataGridView", then you can probably use a 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);
        }
    }

As @DanielHigarth has pointed out, there's no real nice way to do this and I'm not sure why you'd want to...

But, you could:

Use a tool such as postsharp to intercept all calls to byte[].ToString() from your assembly and return whatever you like instead of the actual result.

Use an extension method eg,

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

将Byte数组定义为单独的Class,因此可以为其赋予ToString()覆盖。

How about instead of overriding the .ToString() method, just modify the get function?

for example:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM