Yulian
Yulian

Reputation: 6759

How to print a custom string when a value is null, using .NET's string.Join method?

I have the following class:

public class Point
{
    public int X { get; set; }
    public int Y { get; set; }

    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    public override string ToString()
    {
        return "[" + X + ", " + Y + "]";
    }
}

I have overridden the ToString method, so that if an attempt to store the value of a Point object in a string is made, it could have the following format: '[X, Y]'.

Let's say I have an array of points and I want to print them, separated by a comma.

Point point1 = new Point(1, 2);
Point point2 = new Point(10, 20);

Point[] points = new Point[] { point1, point2, null };

Console.WriteLine(string.Join<Point>(", ", points)); 

This will print '[1, 2], [10, 20],' on the screen. The problem is I want somehow to print '[1, 2], [10, 20], null' - meaning, to print 'null', when I have a null value.

I thought of a workaround, but it's really ugly and incorrect in terms of design. I added the following code inside the Point class:

private bool isNull;

public Point(bool isNull = false)
{
    this.isNull = isNull;
}

public override string ToString()
{
    if (!isNull)
    {
        return "[" + X + ", " + Y + "]";
    }

    return "null";
}

So, now if I call the string.Join method, by writing this:

Point[] points = new Point[] { point1, point2, new Point(true) };

I get the desired output '[1, 2], [10, 20], null]', but as I wrote I think this is ugly and incorrect, so can anyone help me with this?

I really need to use the string.Join method with an array of Point objects.

Upvotes: 4

Views: 4697

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1062840

You can't change how Join interprets null, so: change the fact that there is null in the first place; this works:

Console.WriteLine(string.Join(", ", points.Select(Point.Render)));

where Point.Render is:

internal static string Render(Point point)
{
    return point == null ? "null" : point.ToString();
}

However, I wonder if this might be preferable:

public static string Render(IEnumerable<Point> points)
{
    if (points == null) return "";
    var sb = new StringBuilder();
    foreach(var point in points)
    {
        if (sb.Length != 0) sb.Append(", ");
        sb.Append(point == null ? "null" : point.ToString());
    }
    return sb.ToString();
}

with:

Console.WriteLine(Point.Render(points));

Or if you made it an extension method:

Console.WriteLine(points.Render());

Upvotes: 5

Related Questions