Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ToString() for a class property?

Tags:

c#

Supposing I have a class "Item", which has three member variables: string name, decimal quantity and string unit. I have got public get/set properties on all three.

Sometimes, I want to display quantity as text along with correct unit, eg. 10m or 100 feet.

My question is, is it possible to have some sort of ToString() function for properties too, so that their text output can be customized?

Thanks,

Saurabh.

like image 518
virtualmic Avatar asked May 06 '09 11:05

virtualmic


3 Answers

You could implement the IFormatable interface to have different ToString's

public class Item : IFormattable
{
    public string Name;
    public decimal Quantity;
    public string Unit;

    public override string ToString(string format, IFormatProvider provider)
    {
        switch(format)
        {
            case "quantity": return Quantity + Unit;
            default: return Name;
        }
    }
}

This can be used like this:

Item item = new Item();
Console.WriteLine(item.ToString());
Console.WriteLine("Quantity: {0:quantity}", item);
like image 23
Arjan Einbu Avatar answered Oct 19 '22 09:10

Arjan Einbu


It sounds like your object model isn't correctly factored. What you probably want to do is abstract Unit and Quantity into another object and then you can override ToString for that. This has the advantage of keeping dependent values together, and allowing you to implement things such as conversions between units in the future (e.g. conversion from inchest to feet etc.), e.g.

public struct Measure
{
    public Measure(string unit, decimal quantity)
    {
        this.Unit = unit;
        this.Quantity = quantity;
    }

    public string Unit { get; private set; }
    public decimal Quantity { get; private set; }

    public override string ToString() 
    { 
        return string.Format("{0} {1}", this.Quantity, this.Unit);
    }
}

public class Item
{
    public string Name { get; set; }
    public Measure Measure { get; set; }

    public override string ToString() 
    { 
        return string.Format("{0}: {1}", this.Name, this.Measure);
    }
}

Note that I made Measure a struct here as it probably has value semantics. If you take this approach you should make it immutable and override Equals/GetHashCode as is appropriate for a struct.

like image 27
Greg Beech Avatar answered Oct 19 '22 09:10

Greg Beech


What you can do is to make a new (readonly) property returning a formatted version:

public string QuantityAsString
{
    get
    {
        return string.Format("{0} {1}", this.Quantity, this.Unit);
    }
}
like image 95
Fredrik Mörk Avatar answered Oct 19 '22 09:10

Fredrik Mörk