Redundant ToString code? - c#

I was wondering :
writing this code :
DataRow[] g = new DataRow[1] ;
var t=new StringBuilder().AppendFormat("{0}", g[0]["aaa"].ToString());
Resharper shows it like : ( notice the gray )
3 questions please
1) removing ToString() , how will the object will output its display string without calling the removed ToString() ?
2) does it suggest to remove it because he already calls it internally ? or because of another reason ?
3) not removing ToString() , will it call it twice ?

Yes, it is redundant because AppendFormat (like String.Format) internally already converts it to a string and String.ToString is always redundant.
Actually it uses the ICustomFormatter.Format method on every provided parameter.
It's also redundant in terms of useless. So even if no work needs to be done multiple times(AppendFormat will not try to convert a string to a string), it is pointless since AppendFormat would do it anyway. Hence resharper tries to simplify your code here.

You may want to see: Composite Formatting
Processing Order
Each value in the parameter list that corresponds to a format item is
converted to a string by performing the steps in the following list.
If any condition in the first three steps is true, the string
representation of the value is returned in that step, and subsequent
steps are not executed.
If the value to be formatted is null, an empty string ("") is returned.
If the composite formatting method includes a parameter of type IFormatProvider that also implements the ICustomFormatter interface,
the value is passed to the ICustomFormatterFormat method.
If the value implements the IFormattable interface, its IFormattableToString method is called.
The type's ToString method, which is either overridden or inherited from the Object class, is called.
Whereas DataRow seems to inherit from System.Object and doesn't implmenet IFormatProvider or IFormattableToString, so I believe, its ToString method is called to get the string representation internally, and having explicit .ToString is considered redundant.

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.

Exception's ToString() method

I found in someones code following :
catch (Exception exception)
{
Console.WriteLine(exception.ToString());
}
Resharper is graying out the ToString() call which is as always a great suggestion.
How does this C# code work without it ? Will ToString() be called implicitly ?
Console.WriteLine has an overload that takes an object. This object's ToString method is called internally so there's no need for you to add ToString in the first place.
If the exception is being used within a string... For example "something" + exception.ToString() or String.Format("... {0}", exception), then yes, ToString will be called without you having to call it explicitly.
And... as you updated your example, calling Console.WriteLine() against any object value, ToString will be called. Here's the documentation, with as much detail as you could possibly want.
I assume the something is string concatenation or used as a parameter in a formatted string, then yes, ToString is called implicitly.
UPDATE FOLLOWING QUESTION UPDATE
Console has an overload of WriteLine that accepts an object argument, in this version on the method ToString is called if the passed instance is not null - R# is aware of this and suggests the choice of the preferable overload.

type casting in c#.net

i want to know typecasting in c# .net, i have below lines of code.
int i=4
object o = i // This works properly without any typecasting becausing boxing takes place automatically
string s= i // This does not work, even when the string is also reference type?
string s=(string)i //This also does not work even if i try to typecast the int to string.
string s= Convert.ToString(i); // this works.
so i want to know why string s = i and string s = (string)i does not work and whats the difference in using (string)i, i.ToString(), and Convert.ToString(i).
When it comes to boxing and unboxing, types have explicit and implicit casting. So, in some circumstances, it is easy enough for the runtime to allow for implicit conversion between two supported types, say an Int32 to a Double. However, there is no implicit or explicit conversion between an integer and a string, because obviously, a string is not an integer (despite the fact that a string can contain characters for an integer).
string s = i; // attempt at implicit cast from Int32 to String, error
object o = i; // all types inherit from Object, so you may implicitly or explicitly cast from Int32 to Object.
s = (string)i; // attempt at explicit cast from Int32 to string, error
s = i.ToString(); // conversion
s = Convert.ToString(i); // conversion
That's where Convert comes to play. Convert contains support for attempting to convert known primitives (and types supporting IConvertable) to another. So, ToString or Convert.ToString would be the preferred methods (ToString and Convert.ToString are virtually synonymous, except that ToString gives you some formatting options).
Well, string and object - both of them are reference types. However, object is a root type for all .NET types.
When you use such syntax as (string)i, you are trying to use explicit conversion beetween types. But this conversion type requires string class to know about all possible argument types.
So we have .ToString() method, which can be overriden in any class, and its return value is used as a string represenation of any object.
string s = i and string s = (string)i does not work
because I is not a string, and type CASTING is a CAST of the type, not a conversion. It only works if i contains a string or a subclass of string (which is not possible for strings, but may be for other classes).
whats the difference in using (string)i, i.ToString(), and Convert.ToString(i).
(string) i: cast i to a string, must be assignable.
i.ToString(): calls the ToSstring method, which is defiend on System.object, thus available on ALL classes and structs - but returns no sensible content if not overwritten.
Convert.ToString(i): coonverts i to a string. THis includes calling a converter which likely just calls ToString on this rare case.
At the end, casting is not aconversion. for (string) i to work i HAS TO BE A STRING, while convert tries to MAKE it a string.
You can specify implicit and explicit conversions in .net, the reason that string s = i fails is that there is no built in cast operation for an integer to a string.
see this MSDN article on casting for further information
string s= i does not work because the types don't match, int won't go into a string.
string s=(string)i does not work because it cannot asume which type conversion is to be used (i.e which base)
something like s = ""+i would work on the other hand as it would asume base 10 conversion.
so i want to know why string s = i and string s = (string)i does not work
The short answer is that there is no implict (first example above) nor explicit (second example above) cast from int to string defined. Slightly longer answer; when authoring the struct Int32 in C# no casting behaviour was programmed to enable the developer to automagically cast from an int to a string
whats the difference in using (string)i, i.ToString(), and Convert.ToString(i)
Well, the first doesn;t work as you said, and as ive explained above. The second calls the ToString method on the struct Int32, which returns (as the name implies) a string representation of the object. It should be noted that this is a brand new string, not in any way related to the original value. The third example Convert.ToString will, under the hood, call whatever the most appropriate way to turn the parameter passed in to a string - most likely just calls the ToString method - so pretty much identical to example 2.
ToString() method is override by each referance which is vitual method in the object class. string calss override that method and provide string value out of this.
The default implementation of the ToString method returns the fully qualified name of the type of the Object, as the following example shows.
Object obj = new Object();
Console.WriteLine(obj.ToString());
// The example displays the following output:
// System.Object
this behavior is inherited by reference types that do not override the ToString method.
Typecasting in C# only works along the lines of class inheritance. Object is the root of all types in C# and therefore all values can be typecast to it.
string and int do not share the same branch of inheritance and so cannot be directly cast from one to the other.
Convert.ToString() is a method designed to convert an integer to a string - there's no typecasting going on, it's just executing a method designed to convert an integer to a string representation.
i.ToString() performs the equivalent functionality to Convert.ToString(), except that i.ToString() has overloads which allow greater flexibility on the representation of the number in string format.
One last note, exceptions to the typecasting rules can be included by the developer by using a public static explicit operator method which permits the developer to convert one value to another as they see fit.
First thing to note is that every class derives from object.
Casting int to object is using an Int32.
Casting string to object is using a String.
There is no implicit cast from an integer to a string because they are in different parts of the class hierarchy - one does not in any way relate to another. However because string is used so often for output object (and therefore all its children) have a ToString() method for convenience.
However Convert is written specifically to be able to convert from one type to another, for example Convert.ToBool(x) can parse "true" or "false" to boolean, and as you have shown it can convert an integer to a string - again this is really a convenience that probably just calls Int32.ToString() under the hood.

What is the difference between xxx.tostring() and (string)xxx?

whats the difference in the two string methods below?
string str1 = dr["RAGStatusCID"].ToString();
string str2 = (string)dr["Description"];
This will depend on what dr is. The first invokes the ToString method that each object could override on the indexer of the dr["RAGStatusCID"]. The second casts the dr["Description"] variable to a string.
If we use our telepathic skills and suppose that dr is a SqlDataReader then the two expression do pretty much the same thing except that the cast might throw an exception at runtime if the Description column is not a string.
You haven't mentioned the type of dr or what it's indexer operation returns, but ostensibly, these are two very different operations.
The first invokes the get indexer of dr and calls the ToString() method on the returned reference, allowing the object that reference refers to to provide a string representation of it's data. The generial intent of this is to allow the object itself to return a meaningful representation of itself as a string.
The second call attempts to cast the reference returned by the indexer to System.String. The object returned must either be an instance of System.String or must be a type that the compiler can invoke a custom conversion operator on. Here, the intent is to ensure that the object returned can be treated as an instance of System.String. You can read more about conversions (including user-defined ones) on MSDN.
First one calls the method that returns the string. Someone has to implement ToString method. Second one is just unboxing.
string str1 = dr["RAGStatusCID"].ToString();
This calls the .ToString() method on the object returned from the dr["RAGStatusCID"] call. It is guaranteed to return a string or null.
string str2 = (string)dr["Description"];
This attempts to cast the object returned by dr["Description"] to a string. If the object returned is not a string, then an exception is thrown.
in short, .toString() is a method, just like any other, (String) is a cast, a language construct used to treat one data type as another, compatible type.
Now for some detail:
.toString() is a method, just like any other method you may encounter. Its often thought to be a 'special' method in some way, but it isnt really, all it does is return a string. because its a member of the base Object type, it can be relied upon to be available in every object. For this reason it is generally used to provide a textual representation of the object of which it is member. By default, in c# this is the name of the type of the object. It is often desirable to override this method to provide a more meaningful name, but all it needs to do is return a string, this can be any string you like.
As noted before, theres nothing special about it, and you could just as easily have methods called ToInt(), ToDouble(), and ToChar() to provide the same functionality for there respective types.
Casting is a language construct, this means its built into the language and is implemented specifically for that language. It is used to enable compatible but different types to be used in different locations without the need for an explicit conversion.
xxx.ToString() calls a method on that object to convert it into a string object. (string)xxx assumes that the type of the object is already a string and simply performs a cast on the existing object. So in the first case a conversion happens, in the second it's just identifying the type explicitly.
To put it more succinctly, if in your example RagStatusCID is an integer and you attempted to call (string)dr["RagStatusCID"] you would get an exception because the type is not a string, it's an int. Calling .ToString() performs a conversion and the output is a string.
(string) is a casting operation. .ToString() is a method that is inherited from the Object class. Everything has a .ToString(), but not everything has a (string). Additionally certain objects will cast to a string different than the one .ToString() outputs.
I don't know if it is correct for C# but it probably is, so:
(String)myinstance calls implicitly the .toString() implementation of myinstance's class
if you have a class like this:
class User
{
private integer userId;
private integer userName;
... some code here...
public toString()
{
return "Username: " + this.userName + " (" + this.userId + ")";
}
}
with the method toString you are defining what (String)instance casting will do
User myuser = new User("Alex", 22);
String myuserdump = (String)myuser;
print(myuserdump);
will print "Username: Alex (22)"

Why is there an overload for String.Concat() which accepts one parameter in .NET

Noticed this today when a patch was submitted with the following line:
lblCompletionTime.Text = String.Concat(trainingSkill.EndTime.ToLocalTime())
I can understand why the contributor used that syntax as above line concatenated two strings to form a multi-part date/time string.
Is there some hidden reason for having a single parameter overload of String.Concat() or was it included for "completeness" by the language designers.
I have replaced the line with:
lblCompletionTime.Text = trainingSkill.EndTime.ToLocalTime().ToString(CultureInfo.CurrentCulture)
Which has the same output.
String.Concat(Object) gives you String.Empty when you pass null; ToString would crash with a null pointer exception.
I agree that it doesn't make much sense especially considering the fact that this is the implementation:
public static string Concat(object arg0)
{
if (arg0 == null)
{
return Empty;
}
return arg0.ToString();
}
But it does validate that the argument isn't null so I guess that is something. Still you aren't concatenating anything so I think that this method could have been called
String.ToStringSafe(Object obj) { }
or something similar to better express what the function actually does.
According to MSDN, String.Concat(object)
Creates the String representation of a
specified object.
By looking at the documentation of String.Concat(object), the only advantage I see is that it accepts a null and returns an empty string, which can be an advantage when compared with object.ToString() which would throw a NullReferenceException.
In your example it doesn't help because if trainingSkill.EndTime is null the program will break when invoking ToLocalTime.
I preffer your correction, but I think there's no need for passing CultureInfo.CurrentCulture as a parameter since it is the default behaviour of DateTime.ToString()
In C# it may have little value (aside from the automatic empty string for a null value).
In .Net in general, I could this method signature being very useful in a functional language.
Using String.Concat(Object) to convert an object to a string is the behavior that overload of the function was designed for.
String.Concat Method (Object)
Creates the String representation of a specified object.

Categories