In the Java world we have Apache Commons' ToStringBuilder to help with creating toString() implementations.
Does anyone know of a decent free implementation for C#? Are there better alternatives I don't know about?
If no free implementation exists than I guess this question becomes more of a question of "What would make a good ToStringBuilder in C# 3?"
Off the top of my head:
It could offer both reflection and manual ToString string creation.
It would be really cool if it could make use of Expression trees.
Something like this..
public override string ToString()
{
return new ToStringBuilder<Foo>(this)
.Append(t => t.Id)
.Append(t => t.Name)
.ToString();
}
Which would return:
"Foo{Id: 1, Name: AName}"
Any other ideas?
UPDATE
Just to clarify ToStringBuilder is a different creature to StringBuilder.. I'm looking for something akin to the functionality of Apache Common's ToStringBuilder, it has features such as multi-line formatting, different styles and reflection base ToString creation. Thanks.
UPDATE 2
I've built my own. See here.
EDIT: OK, you want to use reflection so you don't have to type property names. I think this will get you what you're after:
// forgive the mangled code; I hate horizontal scrolling
public sealed class ToStringBuilder<T> {
private T _obj;
private Type _objType;
private StringBuilder _innerSb;
public ToStringBuilder(T obj) {
_obj = obj;
_objType = obj.GetType();
_innerSb = new StringBuilder();
}
public ToStringBuilder<T> Append<TProperty>
(Expression<Func<T, TProperty>> expression) {
string propertyName;
if (!TryGetPropertyName(expression, out propertyName))
throw new ArgumentException(
"Expression must be a simple property expression."
);
Func<T, TProperty> func = expression.Compile();
if (_innerSb.Length < 1)
_innerSb.Append(
propertyName + ": " + func(_obj).ToString()
);
else
_innerSb.Append(
", " + propertyName + ": " + func(_obj).ToString()
);
return this;
}
private static bool TryGetPropertyName<TProperty>
(Expression<Func<T, TProperty>> expression, out string propertyName) {
propertyName = default(string);
var propertyExpression = expression.Body as MemberExpression;
if (propertyExpression == null)
return false;
propertyName = propertyExpression.Member.Name;
return true;
}
public override string ToString() {
return _objType.Name + "{" + _innerSb.ToString() + "}";
}
}
Example:
// from within some class with an Id and Name property
public override string ToString() {
return new ToStringBuilder<SomeClass>(this)
.Append(x => x.Id)
.Append(x => x.Name)
.ToString();
}
Behold, the behavior you're after:
class Thing {
public int Id { get; set; }
public string Name { get; set; }
public override string ToString() {
return new ToStringBuilder<Thing>(this)
.Append(t => t.Id)
.Append(t => t.Name)
.ToString()
}
}
void Main() {
var t = new Thing { Id = 10, Name = "Bob" };
Console.WriteLine(t.ToString());
}
Output:
Thing{Id: 10, Name: "Bob"}
The original question concerned C# 3.5 but since then I've upgraded to C# 4.
I thought I'd share my new version here in case it's of benefit to others. It has all of the features mentioned in this thread and compiles at runtime to a fast Stringify method.
Get it here: ToStringBuilder
It might not be exactly what you are after since it is not free, but Resharper will do this. It is a fantastic plugin to visual studio that does a lot more than generate ToString. But it will do that to. put your cursor inside your class, hit alt+insert and choose formating members.
Use .NET's StringBuilder.
Note that you'll have to provide a little template yourself.
E.g:
public StringBuilder ToStringBuilder<T>(T type) where T : IYourInterface
{
StringBuilder sb = new StringBuilder();
sb.append(type.key);
// more appends
return sb;
}
Provided a kinda generic
way here.
You'll be able to create your own neat solution with the System.Reflection
namespace in .NET
Cheers
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With