Should we always specify ToString() explicitly? - c#

I have a custom class structure as follows.
public interface Stuff { }
public Thing : Stuff
{
public new String ToString() { return "That's the thing!"; }
}
Then, in other parts of my code I have a method that takes a String object as a parameter. The first line compiles, while the second one doesn't. I thought that ToString was called by default when sending in an object. And Stuff, being inherited from Object class should have ToString already implemented (and also, in my case, shadowed by my implementation).
Thing thing = new Thing();
MustHaveString(thing.ToString());
MustHaveString(thing);
What do I miss?

You're probably getting confused because of calls such as String.Format and Console.WriteLine, as well as string concatenation operator, which call ToString implcitly.
This isn't a general rule though. In general, if you need a string, you need to either call ToString explicitly or have some other conversion. I wouldn't recommend creating implicit conversions to string - they're likely to cause more pain than joy.
I'd also recommend against creating a new ToString method. Instead, you should override the one declared by object. Hiding methods is almost always a bad idea; there are a few cases where you really want to do it (e.g. to change the return type) but it should be avoided where possible.

Assuming MustHaveString looks something like:
public void MustHaveString(string arg)
Then simply saying thing results in a compile error, unless thing has an implicit conversion to string. Without the implicit conversion, you must do thing.ToString(). If, however, your code is like:
string myString = "This is a thing: " + thing;
Then the ToString is implicitly called, so it's optional.
In most cases, I would recommend explicitly calling the ToString method, to make it clear to people reading your code what's going on.
Edit: since this answer was accepted, I thought I should also mention that you should make your ToString() method an override, not a new. This will result in the normally-expected behavior, which is what I described above.

Related

Explicit vs implicit call of ToString()

Is there any benefit in calling the ToString() method on a string builder when the method call accepts the type object as it's parameter?
StringBuilder sb = new StringBuilder("Hello");
System.Console.WriteLine(sb);
OR
System.Console.WriteLine(sb.ToString());
From what I know the WriteLine takes an object as an overload, my guess is the ToString() method is then called on the object, which then calls the StringBuilder.ToString() method and returns the expected string value.
So again, is there any benefit in explictly calling ToString()? Could you please justify your answer?
"my guess is the ToString() method is then called on the object"
If you look at MSDN you see that there is no overload that consumes a StringBuilder directly, so the one which accepts anything(object) is used.
So your guess was correct, it will just call ToString.
If value is null, only the line terminator is written. Otherwise, the
ToString method of value is called to produce its string
representation, and the resulting string is written to the standard
output stream.
Then i would prefer to call it myself since it's more readable and you gain nothing by passing the StringBuilder.
The only benefit is that it is clear what you're doing. If you can state something explicitly do it - it makes the code more readable.
Is there any benefit in explicitly calling ToString()?
Console.WriteLine(object) will first check if the object is null and if so simply output an empty line. Calling ToString on a null object will result in a NullReferenceException.
So WriteLine(object) has built in null-safety, and the result for null will be the same as a non-null object that outputs an empty string. Depending on the context, that null safety could be convenient, or it could cause undesired behavior.
In short, it's more beneficial to call ToString() if you don't want a NullReferenceException to be suppressed.
No, there's no benefit. Tools with good static analysis capabilities like ReSharper will actually let you know that the call is redundant and can be safely removed.

Method naming depending on returntype

Trying to avoid Tell-don't-ask, I want to combine a bool property that I was asking before calling a method, into a new method returning bool.
I try to follow the pattern, that if a method can't perform the action implied by it's name, it will throw an exception. For example if SendMail can't send the mail, it will throw an exception.
I want this particular method to return a bool to indicate the success. And am considering if I should change the name to something like TrySendMail, perhaps looking at the method signature with the bool return type should be enough?
Naming the method TrySendMail seems like a not too bad approach. However, being consistent with your overall naming sceme is the most important thing.
The whole TryWhatever naming pattern seems to be a fairly recent thing coming from Microsoft, but the behavior (try to do something, throw if it fails, return a meaningful strongly-typed value if it doesn't) has been around for a long time.
In theory, TryWhatever should be used if the method takes a ref parameter that receives the result, and returns a bool. If the method fails, it returns false. If it succeeds, the result is stored in the ref parameter (always the last parameter), and returns true.
You can use the DateTime.TryParse method as an example. If the method doesn't match that pattern, it's not a candidate for this naming convention.
For me, when using this convention, consistency is key. Don't surprise developers. Some of us are very scary people!
The TrySomething pattern is, as you know, used in several .NET BCL methods (various TryParse methods), and people are accustomed to it, so it shouldn't surprise anyone.
If your method's signature is simply bool TrySendMail(Mail mail), then it should be pretty obvious what's going on. And I would prefer to see that signature over something like:
bool WasMailSentSuccessfully(Mail mail);
because it is not so clear from the latter method that the method is actually sending the mail. So you are making the right naming choice if you go with the Try prefix, as far as I am concerned.
On the other hand, when I see the Try prefix, I usually expect to see the out keyword inside the argument list, which would follow these conventions:
bool TrySendMail(Mail mail, out string error);
And be used as:
string error = null;
if (!TrySendMail(mail, out error))
Console.WriteLine(error);
This convention, although pretty common, is actually rather ugly from an OOP point of view. It is basically a method which returns two values, and instead of passing one of the arguments by reference, a proper OOP way would be to wrap all of the return values in a new class.
So I would prefer something like:
SendResult SendMail(Mail mail);
and then you could use it like this:
SendResult sendResult = SendMail(mail);
if (!sendResult.Success)
Console.WriteLine(sendResult.Value);
where SendResult could be something like:
public class SendResult : ActionResult<string>
{ ... }
public class ActionResult<T>
{
public bool Success { get; private set; }
public T Value { get; private set; }
public ActionResult<T>(bool success, T value)
{
Success = success;
Value = value;
}
}
The benefit is that later adding a bunch of additional return values does not change your method's signature.
I remember reading a piece in Code Complete 2 (although I can't remember where abouts exactly) about naming conventions, aside from trying to keep them generic so they can be used for multiple applications they should all have some consistency. In this case calling it "SendMail" keeps it straight to the point and allows you to easily reuse it without the user having to worry about the implementation details, it's obvious what it does.
Setting the return type as a boolean should be a sure sign that the method works on a Success/Fail operation, making the "Try" part redundant.
private bool SendMail()
{
try
{
//Send mail
return true;
}
catch()
{
//Handle exception
}
return false;
}
If you were to add the XML header for the method you can even add an explanation as to what the method does when you try to call it through IntelliSense.
Be careful with the exceptions. For instance, if the address passed into the SendMail is badly formed, I don't think it appropriate to throw an exception. Exceptions are for exceptional behaviour, and to my mind not sending a mail because the address is badly formed is expected behaviour, not exceptional. I would definitely return a false (and maybe a string reason) if the mail isn't sent rather than throwing an exception. Throwing exceptions is not just slow, but means that the stack gets unwound so has to worry about leaving everything in a good state.

What do 2 brackets in a row mean in xaml.cs?

Just started learning C# (in xaml), so appreciate some elaboration:
((MSAvalon.Windows.Serialization.ILoaded)(_Text_2_)).DeferLoad();
Not sure what all the round brackets means... does it mean "_Text_2_" is a child of object "MSAvalon.Windows.Serialization.ILoaded" ?
and if so... why not just something like:
MSAvalon.Windows.Serialization.ILoaded._Text_2.DeferLoad();
_Text_2_ is casted to a MSAvalon.Windows.Serialization.ILoaded Object/Interface and then the method DeferLoad is called
This is a typecast, used to tell the compiler that a variable is of a particular type when it's not obvious. It could have been used like this:
class Foo {
private object _Text_2_;
void Method() {
((MSAvalon.Windows.Serialization.ILoaded)_Text_2_).DeferLoad();
}
}
Leaving out the typecast here would cause a compiler error, since DeferLoad is not a method of object. You're telling the compiler here that you have some special knowledge that _Text_2_ is really what you say it is.
Basically it's started with (( so that DeferLoad can be called. I'll illustrate with an example.
Lets say you do the following.
object s = "Hello world";
s now contains a string. If you want to make this string uppercase using a cast (as in your example, I can't simply write this
(string)s.ToUpper();
ToUpper() can't be called, since it's not valid on a variable of type object. If you rewrite this to
((string)s).ToUpper()
it's valid. Because of the brackets, s is casted to a string first, then string.ToUpper() is called on the variable.
Note that in this case (s as string).ToUpper() would be a cleaner approach.

Method writing pattern

I recently noticed the following code which basically defines a class method
public Func<string, string> SampleMethod = inputParam =>
{
return inputParam.ToUpper();
};
which is the same as doing it in the old fashioned way
public string SampleMethod(string inputParam )
{
return inputParam.ToUpper();
}
My question - why would I prefer the first over the second? My eyes are maybe more trained to understand the second style quicker. I find it similar to the difference between SMS lingo and plain old english.
Those two things are fundamentally different. The former is a field of a delegate type while the latter is really a method. The tiniest difference I can think of is that you can modify the first one dynamically at runtime and assign another method reference to it while the second is fixed.
You shouldn't normally prefer the first over the second if your purpose is to write a simple method for a class in C#.
An example that makes the first extremely fragile:
var c = new SomeClass();
c.SampleMethod = inputParam => inputParam.ToLower();
c.DoSomeTaskThatReliesOnSampleMethodReturningAnUpperCaseString();
c.SampleMethod = null;
c.DoSomeTaskThatCallsSampleMethod(); // NullReferenceException
This style of programming is common in language like Javascript where an object is fundamentally a dynamic creature built upon a simple dictionary.
They are actually not the same at all. The second is a regular member method, that returns ToUpper on the input string.
The first, on the other hand, is a Func member variable, that happens to point to a delegate, that implements the same functionality. However, as this is a method pointer, you can substitute the delegate with any other delegate of the same type at runtime. I.e. you can completely redefine what it means to call this method.
One benefit of the second way is it's better from a unit testing perspective - you can test your class and know that the method will correctly return the uppercase string. With the first method, you can change the method at runtime, so unit testing is much harder.

Casting vs Converting an object toString, when object really is a string

This isn't really an issue, however I am curious. When I save a string in lets say an DataRow, it is cast to Object. When I want to use it, I have to cast it ToString. As far as I know there are several ways of doing this, first is
string name = (string)DataRowObject["name"]; //valid since I know it's a string
and another one is:
string name = DataRowObject["name"].ToString();
I am interested in what is the difference between both? Is the first more efficient? (This is just a speculation, in my head ToString() method is implemented by some looping mechanism where just casting it "could" be faster, however this is just a "gut feeling" I have).
Is there even a faster / more elegant way of doing this?
Can anyone clear this up for me?
The two are intended for different
purposes. The ToString method of any
object is supposed to return a string
representation of that object. Casting
is quite different, and the 'as' key
word performs a conditional cast, as
has been said. The 'as' key word
basically says "get me a reference of
this type to that object if that
object is this type" while ToString
says "get me a string representation
of that object". The result may be the
same in some cases but the two should
never be considered interchangeable
because, as I said, they exist for
different purposes. If your intention
is to cast then you should always use
a cast, NOT ToString.
from http://www.codeguru.com/forum/showthread.php?t=443873
see also http://bytes.com/groups/net-c/225365-tostring-string-cast
If you know it is a String then by all means cast it to a String. Casting your object is going to be faster than calling a virtual method.
Edit: Here are the results of some benchmarking:
============ Casting vs. virtual method ============
cast 29.884 1.00
tos 33.734 1.13
I used Jon Skeet's BenchmarkHelper like this:
using System;
using BenchmarkHelper;
class Program
{
static void Main()
{
Object input = "Foo";
String output = "Foo";
var results
= TestSuite.Create("Casting vs. virtual method", input, output)
.Add(cast)
.Add(tos)
.RunTests()
.ScaleByBest(ScalingMode.VaryDuration);
results.Display(ResultColumns.NameAndDuration | ResultColumns.Score,
results.FindBest());
}
static String cast(Object o)
{
return (String)o;
}
static String tos(Object o)
{
return o.ToString();
}
}
So it appears that casting is in fact slightly faster than calling ToString().
Basically in your case it is better to leave type cast because .ToString() may hide bugs. For example, your data base schema changed and name is no longer of string type but with .ToString() your code still works. So in this case it is better to use type cast.
Here is implementation of String.ToString() - nothing special =)
public override string ToString()
{
return this;
}
Downcasting is a relatively slow operation since CLR has to perform various runtime type-checks. However, in this particular scenario casting to string is more appropriate than calling ToString() for the sake of consistency (you can't call ToInt32 on object, but cast it to int) and maintanability.
I want to make one more comment
If you are going to use casting: string name = (string)DataRowObject["name"]
you will get an Exception: Unable to cast object of type 'System.DBNull' to type'System.String' in case if the record in the database table has null value.
In this scenario you have to use: string name = DataRowObject["name"].ToString() or
You have to check for null value like
if(!string.IsNullOrEmpty(DataRowObject["name"].ToString()))
{
string name = (string)DataRowObject["name"];
}
else
{
//i.e Write error to the log file
string error = "The database table has a null value";
}
For data object, I suggest you to use "as" keyword like the following code.
string name = DataRowObject["name"] as string;
Please check it before you use value.
if(name != null)
{
// statement for empty string or it has value
}
else
{
// statement for no data in this object.
}
In this case:
string name = DataRowObject["name"].ToString();
since it is a string, I think that the ToString() method of a string object is simple as:
return this;
so IMHO there is no performance penalty.
PS
I'm a Java programmer, so this anwser is only a guess.
ToString() does not perform a cast by default. Its purpose is to return a string that represents the type (e.g. "System.Object").
If you want to avoid casting you could try to think of an implementation that is strongly typed (using generics, for example) and avoids DataRowObject altogether.
I know you mentioned that the Object is a string, but incase you're afraid that the returned object is null, you can also cast using "Convert.ToString(DataRowObject["name"]);" This has the added benefit of returning an empty string (string.empty) if the object is null, to avoid any null reference exceptions (unless of course you want an exception thrown in such cases).

Categories