C# adding string + null doesn't throw an error? - c#

As a programmer I would have expected this to throw an exception. Is there a reason why it treats null as ""?
string s = "hello";
string t = null;
Console.WriteLine(s + t);
Output:
hello
Just to emphasise my question, do you know why the decision to turn null into String.Empty was made? I was expecting some string to be added but there was a problem further back where it wasn't retrieving it properly and it came back with null. The problem went unnoticed!
Here's a pseudocode of why I think it is bad (and why I was shocked to discover no error):
You can assume I overloaded ToString to give the name of the person or details about them.
Person p = PersonDatabase.GetForName("Jimmy Gibbs");
Console.WriteLine("Name is: " + p.ToString());
Throws an exception because p is null
String p = PersonDatabase.GetForName("Jimmy Gibbs").Name;
Console.WriteLine("Name is: " + p);
Doesn't throw an exception, even though p is null (it treats it as "").
(If you want to be picky and say I won't be able to get Name as GetforName will be null, think of it as this:)
String p = PersonDatabase.GetNameFromID(1234); // Returns a string or null if not found
Console.WriteLine("Name is: " + p);
(If you use this value in a list or array you'll end up with a blank entry which is what broke for me, it was creating javascript and trying to get element by ID of "")

From the C# Language Specification:
7.8.4 Addition operator
String concatenation:
string operator +(string x, string y);
string operator +(string x, object y);
string operator +(object x, string y);
These overloads of the binary +
operator perform string concatenation.
If an operand of string concatenation
is null, an empty string is
substituted. Otherwise, any non-string
argument is converted to its string
representation by invoking the virtual
ToString method inherited from type
object. If ToString returns null, an
empty string is substituted.

The + operator is emitted as string.Concat in the resulting IL.
s + t = string.Concat(s, t)
and when looking at the implementation it checks whether arguments are null and returns string.Empty:
Disassembled with reflector:
[SecuritySafeCritical]
public static string Concat(string str0, string str1)
{
if (IsNullOrEmpty(str0))
{
if (IsNullOrEmpty(str1))
{
return Empty;
}
return str1;
}
if (IsNullOrEmpty(str1))
{
return str0;
}
int length = str0.Length;
string dest = FastAllocateString(length + str1.Length);
FillStringChecked(dest, 0, str0);
FillStringChecked(dest, length, str1);
return dest;
}

When thinking about design decision that was made, we should look not only at plus operator for Strings but also at related classes and methods, e.g. String.Concat(String, String) and StringBuilder.Append(String). Those classes are part of Base Class Library which in widely used in other languegges (e.g. Visual Basic and F#).
From language and platform design perspective, all those methods should behave in a consistent faction (i.e. treat null in the same way). I see three possible options:
Throw exception
This is a "safe" solution since it's not clear what to do with null. As a tradeoff, it would require a more defensive style of programming and more verbose code.
Use some representation for null e.g. <null>, null or [null] (Java-style)
This is an outcome that you expected. It is not clear why this should happen and how exactly null should be represented.
Treat null in the same fashion as empty string (.NET-style)
The idea behind it is that textual representation of null (i.e. an object that is missing) is an empty string. In that case, a programmer can exploit this behavior and write shorter code. On the other hand, it can hide bugs.
Some decision had to be made and I think that there's no obvious choice. Expected behavior in C# and other .NET languages is clearly documented and it's consistent across all the methods that deal with concatenation.

In string concatenation operations, the C# compiler treats a null string the same as an empty string, but it does not convert the value of the original null string. Additional information here http://msdn.microsoft.com/en-us/library/aa691375(VS.71).aspx

If I have an Orange and add another Orange, I now have two oranges.
If I have an Orange and add NOTHING, I still have an orange.
To me adding NULL to a string and getting the original string seems perfectly intuitive and semantic. NullReferenceExceptions should be reserved for when accessing Properties or instance methods on instances that don't exist, eg.
string myString = null;
string lowerCaseString = myString.ToLower();
Would understandably throw a NullReferenceException because I'm trying to access the ToLower() instance method on a reference that doesn't exist hence Null Reference Exception (ie. there's a thing on the Stack, but nothing on the Heap).
Having NULL string concat operations throw exceptions would mean tonnes of extra defensive NULL code checks when dealing with strings, which are annoying. Sorry, but I happen to agree with how C#.NET handles this. Doesn't Java do the same?
If you want to check if a string contains a value then use String.IsNullOrEmpty(myString); or String.IsNullOrWhitespace(myString); (only in .NET 4.0)

User defined operators are just static methods and of course can accept null parameters. This is for example really useful for delegates.
So string accepting null is no technical but a design decision. And it's probably sometimes useful to treat null as "" since a lot of user code treats them the same.

Actually this is how strings are represented.... nothing wrong there.
null is used as a termination character.
For example:
string a: "blahblah[null]"
So whatever reads the string knows to stop at null.
so then when you create a string like this:
string b: "[null]"
it is perfectly valid.
Now, there are no characters before null. so when your program starts reading the string it encounters null (perfectly valid) and stops.... thus... empty string!!

Related

Why cannot I use String.Contains() if default string is null?

From MSDN doc:
public bool Contains(
string value
)
Return Value: true if the value parameter occurs within this string, or if value is the empty string (""); otherwise, false.
Exception: ArgumentNullException: value is null.
Example:
string s = string.Empty; //or string s = "";
Console.WriteLine(s.Contains("Hello World!")); //output: False
If I change it to:
try
{
string s = null; //or string s;
Console.WriteLine(s.Contains("Hello World!"));
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
It'll throw an error message: Object reference not set to an instance of an object since string doesn't have a default value (like "") from Default Values Table (C# Reference),
Please come back to the example, the code will work if I declare s:
string s = "";
Now, Object s is set to an instance of an object.
So, my question is: Does MSDN forgot something like: s cannot be null?
To check it, I've tried:
string s = null;
Console.WriteLine(!string.IsNullOrEmpty(s) ? s.Contains("Hello World!") : false);
It should work.
You changed the value with the instance.
myString.Contains(anotherString)
Here myString is the instance on which you call the method Contains, whereas anotherString is the value passed to the method. If this value is null the method will throw an ArgumentNullException.
When changing the instance to null on the other hand it surely leads to NRE as you canĀ“t call any member on a null-reference. However if you set it to string.empty Contains will return false because the empty string does not contain anything (in particular string.empty does not contain "Hello World", however "Hello world" contains the empty string).
So the following returns false:
Console.WriteLine(string.Empty.Contains("Hello World"));
Whilst this returns true:
Console.WriteLine("Hello World".Contains(string.Empty));
Anyway what you want to check is if the empty string IS contained in any other one:
var retVal = myString.Contains(string.empty);
Which should return true.
Furthermore myString.Contains(null) leads to ArgumentNullException
On the other side null.Contains(aString) leads to the NRE.
the new compilier allows you to do it with the condition check simplified.
string s = null;
Console.WriteLine(s?.Contains("Hello World!"));
It sounds like this question is more about the difference between value types (which cannot be null) and reference types (which can be). In C# and other OO languages it's to do with memory handling.
The value types listed in your MSDN article are all of a known size - e.g. int will always be 32 bits in size etc. Under the hood, these are all structs. As they are of fixed size regardless of the value, C# stores them on the call stack. As null by definition doesn't refer to anything, it has no size. It doesn't make sense for something that exists with a fixed size to also exist with no size.
If you read the documentation for string on MSDN a little closer, you'll see the string is a class not a struct. This is because a string can be of any length you like, so it has to be stored as a pointer to some data on the heap. When you declare a reference type variable, it creates a pointer on the stack to a location on the heap, but there won't be anything at that address until you give that variable a value. Until then, the pointer for that variable is pointing and memory containing literally nothing - i.e. null and it doesn't make sense to try to find "Hello World!" in nothing. An empty string is still a string, but null is literally nothing.
This is probably more detail than you were expecting, but it's good to have an appreciation of the underlying principles of a language, even if you don't need them day to day. This article is well worth a read if you want to go a little more in depth. The idea of null can be a weird concept to get your head around, but once you get the hang of it, it all makes sense, honest!

Why is the default value of the string type null instead of an empty string?

It's quite annoying to test all my strings for null before I can safely apply methods like ToUpper(), StartWith() etc...
If the default value of string were the empty string, I would not have to test, and I would feel it to be more consistent with the other value types like int or double for example.
Additionally Nullable<String> would make sense.
So why did the designers of C# choose to use null as the default value of strings?
Note: This relates to this question, but is more focused on the why instead of what to do with it.
Why is the default value of the string type null instead of an empty
string?
Because string is a reference type and the default value for all reference types is null.
It's quite annoying to test all my strings for null before I can
safely apply methods like ToUpper(), StartWith() etc...
That is consistent with the behaviour of reference types. Before invoking their instance members, one should put a check in place for a null reference.
If the default value of string were the empty string, I would not have
to test, and I would feel it to be more consistent with the other
value types like int or double for example.
Assigning the default value to a specific reference type other than null would make it inconsistent.
Additionally Nullable<String> would make sense.
Nullable<T> works with the value types. Of note is the fact that Nullable was not introduced on the original .NET platform so there would have been a lot of broken code had they changed that rule.(Courtesy #jcolebrand)
Habib is right -- because string is a reference type.
But more importantly, you don't have to check for null each time you use it. You probably should throw a ArgumentNullException if someone passes your function a null reference, though.
Here's the thing -- the framework would throw a NullReferenceException for you anyway if you tried to call .ToUpper() on a string. Remember that this case still can happen even if you test your arguments for null since any property or method on the objects passed to your function as parameters may evaluate to null.
That being said, checking for empty strings or nulls is a common thing to do, so they provide String.IsNullOrEmpty() and String.IsNullOrWhiteSpace() for just this purpose.
You could write an extension method (for what it's worth):
public static string EmptyNull(this string str)
{
return str ?? "";
}
Now this works safely:
string str = null;
string upper = str.EmptyNull().ToUpper();
You could also use the following, as of C# 6.0
string myString = null;
string result = myString?.ToUpper();
The string result will be null.
Empty strings and nulls are fundamentally different. A null is an absence of a value and an empty string is a value that is empty.
The programming language making assumptions about the "value" of a variable, in this case an empty string, will be as good as initiazing the string with any other value that will not cause a null reference problem.
Also, if you pass the handle to that string variable to other parts of the application, then that code will have no ways of validating whether you have intentionally passed a blank value or you have forgotten to populate the value of that variable.
Another occasion where this would be a problem is when the string is a return value from some function. Since string is a reference type and can technically have a value as null and empty both, therefore the function can also technically return a null or empty (there is nothing to stop it from doing so). Now, since there are 2 notions of the "absence of a value", i.e an empty string and a null, all the code that consumes this function will have to do 2 checks. One for empty and the other for null.
In short, its always good to have only 1 representation for a single state. For a broader discussion on empty and nulls, see the links below.
https://softwareengineering.stackexchange.com/questions/32578/sql-empty-string-vs-null-value
NULL vs Empty when dealing with user input
Why the designers of C# chose to use null as the default value of
strings?
Because strings are reference types, reference types are default value is null. Variables of reference types store references to the actual data.
Let's use default keyword for this case;
string str = default(string);
str is a string, so it is a reference type, so default value is null.
int str = (default)(int);
str is an int, so it is a value type, so default value is zero.
The fundamental reason/problem is that the designers of the CLS specification (which defines how languages interact with .net) did not define a means by which class members could specify that they must be called directly, rather than via callvirt, without the caller performing a null-reference check; nor did it provide a meany of defining structures which would not be subject to "normal" boxing.
Had the CLS specification defined such a means, then it would be possible for .net to consistently follow the lead established by the Common Object Model (COM), under which a null string reference was considered semantically equivalent to an empty string, and for other user-defined immutable class types which are supposed to have value semantics to likewise define default values. Essentially, what would happen would be for each member of String, e.g. Length to be written as something like [InvokableOnNull()] int String Length { get { if (this==null) return 0; else return _Length;} }. This approach would have offered very nice semantics for things which should behave like values, but because of implementation issues need to be stored on the heap. The biggest difficulty with this approach is that the semantics of conversion between such types and Object could get a little murky.
An alternative approach would have been to allow the definition of special structure types which did not inherit from Object but instead had custom boxing and unboxing operations (which would convert to/from some other class type). Under such an approach, there would be a class type NullableString which behaves as string does now, and a custom-boxed struct type String, which would hold a single private field Value of type String. Attempting to convert a String to NullableString or Object would return Value if non-null, or String.Empty if null. Attempting to cast to String, a non-null reference to a NullableString instance would store the reference in Value (perhaps storing null if the length was zero); casting any other reference would throw an exception.
Even though strings have to be stored on the heap, there is conceptually no reason why they shouldn't behave like value types that have a non-null default value. Having them be stored as a "normal" structure which held a reference would have been efficient for code that used them as type "string", but would have added an extra layer of indirection and inefficiency when casting to "object". While I don't foresee .net adding either of the above features at this late date, perhaps designers of future frameworks might consider including them.
Because a string variable is a reference, not an instance.
Initializing it to Empty by default would have been possible but it would have introduced a lot of inconsistencies all over the board.
If the default value of string were the empty string, I would not have to test
Wrong! Changing the default value doesn't change the fact that it's a reference type and someone can still explicitly set the reference to be null.
Additionally Nullable<String> would make sense.
True point. It would make more sense to not allow null for any reference types, instead requiring Nullable<TheRefType> for that feature.
So why did the designers of C# choose to use null as the default value of strings?
Consistency with other reference types. Now, why allow null in reference types at all? Probably so that it feels like C, even though this is a questionable design decision in a language that also provides Nullable.
Perhaps if you'd use ?? operator when assigning your string variable, it might help you.
string str = SomeMethodThatReturnsaString() ?? "";
// if SomeMethodThatReturnsaString() returns a null value, "" is assigned to str.
A String is an immutable object which means when given a value, the old value doesn't get wiped out of memory, but remains in the old location, and the new value is put in a new location. So if the default value of String a was String.Empty, it would waste the String.Empty block in memory when it was given its first value.
Although it seems minuscule, it could turn into a problem when initializing a large array of strings with default values of String.Empty. Of course, you could always use the mutable StringBuilder class if this was going to be a problem.
Since string is a reference type and the default value for reference type is null.
Since you mentioned ToUpper(), and this usage is how I found this thread, I will share this shortcut (string ?? "").ToUpper():
private string _city;
public string City
{
get
{
return (this._city ?? "").ToUpper();
}
set
{
this._city = value;
}
}
Seems better than:
if(null != this._city)
{ this._city = this._city.ToUpper(); }
Maybe the string keyword confused you, as it looks exactly like any other value type declaration, but it is actually an alias to System.String as explained in this question.
Also the dark blue color in Visual Studio and the lowercase first letter may mislead into thinking it is a struct.
Nullable types did not come in until 2.0.
If nullable types had been made in the beginning of the language then string would have been non-nullable and string? would have been nullable. But they could not do this du to backward compatibility.
A lot of people talk about ref-type or not ref type, but string is an out of the ordinary class and solutions would have been found to make it possible.

Why is it Valid to Concatenate Null Strings but not to Call "null.ToString()"?

This is valid C# code
var bob = "abc" + null + null + null + "123"; // abc123
This is not valid C# code
var wtf = null.ToString(); // compiler error
Why is the first statement valid?
The reason for first one working:
From MSDN:
In string concatenation operations,the C# compiler treats a null string the same as an empty string, but it does not convert the value of the original null string.
More information on the + binary operator:
The binary + operator performs string concatenation when one or both operands are of type string.
If an operand of string concatenation is null, an empty string is substituted. Otherwise, any non-string argument is converted to its string representation by invoking the virtual ToString method inherited from type object.
If ToString returns null, an empty string is substituted.
The reason of the error in second is:
null (C# Reference) - The null keyword is a literal that represents a null reference, one that does not refer to any object. null is the default value of reference-type variables.
Because the + operator in C# internally translates to String.Concat, which is a static method. And this method happens to treat null like an empty string. If you look at the source of String.Concat in Reflector, you'll see it:
// while looping through the parameters
strArray[i] = (str == null) ? Empty : str;
// then concatenate that string array
(MSDN mentions it, too: http://msdn.microsoft.com/en-us/library/k9c94ey1.aspx)
On the other hand, ToString() is an instance method, which you cannot call on null (what type should be used for null?).
The first sample will be translated into:
var bob = String.Concat("abc123", null, null, null, "abs123");
The Concat method checks input and translate null as an empty string
The second sample will be translated into:
var wtf = ((object)null).ToString();
So a null reference exception will be generated here
The first part of your code is just treated like that in String.Concat,
which is what the C# compiler calls when you add strings. "abc" + null gets translated to String.Concat("abc", null),
and internally, that method replaces null with String.Empty. So, that's why your first part of code does not throw any exception. it is just like
var bob = "abc" + string.Empty + string.Empty + string.Empty + "123"; //abc123
And in 2nd part of your code throws exception because 'null' is not an object, the null keyword is a literal that represents a null reference, one that does not refer to any object. null is the default value of reference-type variables.
And 'ToString()' is a method that can be called by an instance of an object but not any literal.
In the COM framework which preceded .net, it was necessary for any routine which received a string to free it when it was done with it. Because it was very common for empty strings to be passed into and out of routines, and because attempting to "free" a null pointer was defined as a legitimate do-nothing operation, Microsoft decided to have a null string pointer represent an empty string.
To allow for some compatibility with COM, many routines in .net will interpret a null object as a legal representation as an empty string. With a couple of slight changes .net and its languages (most notably allowing instance members to indicate "do not invoke as virtual"), Microsoft could have made null objects of declared type String behave even more like empty strings. If Microsoft had done that, it would have also had to make Nullable<T> work somewhat differently (so as to allow Nullable<String>--something they should IMHO have done anyway) and/or define a NullableString type which would be mostly interchangeable with String, but which would not regard a null as a valid empty string.
As it is, there are some contexts in which a null will be regarded as a legitimate empty string and others in which it won't. Not a terribly helpful situation, but one which programmers should be aware of. In general, expressions of the form stringValue.someMember will fail if stringValue is null, but most framework methods and operators which accept strings as parameters will regard null as an empty string.
'+' is an infix operator. Like any operator it is really calling a method. You could imagine a the non-infix version "wow".Plus(null) == "wow"
The implementer has decided on something like this...
class String
{
...
String Plus(ending)
{
if(ending == null) return this;
...
}
}
So.. your example becomes
var bob = "abc".Plus(null).Plus(null).Plus(null).Plus("123"); // abc123
which is the same as
var bob = "abc".Plus("123"); // abc123
At no point does null become a string. So null.ToString() is no different that null.VoteMyAnswer(). ;)
I guess because it's a literal which doesn't refer to any object. ToString() needs an object.
Adding null to a string is simply ignored. null (in your second example) isn't an instance of any object, so it doesn't even have a ToString() method. It's just a literal.
Someone said in this discussion thread that you can't make a string out of nothing.
(which is a nice phrase as I think). But yes - you can :-), as the following example shows:
var x = null + (string)null;
var wtf = x.ToString();
works fine and does not throw an exception at all. The only difference is that you need to cast one of the nulls into a string - if you remove the (string) cast, then the example still compiles, but throws a run-time exception: "Operator '+' is ambiguous on operands of type '<null>' and '<null>'".
N.B. In the code example above, the value of x is not null as you might expect, it is actually an empty string after you have casted one of the operands into a string.
Slightly different is var a = ((string)null).ToString(); - which compiles but will throw a NullReferenceException. In this case the exception is thrown because the . operator isn't allowed on null values. Using ?. would work here (but ToString isn't executed in this case). The compiler will correctly "create" the variable a as a string.
Another interesting fact is that in C# / .NET the way null is treated is not always the same if you regard different data types. For example:
int? x = 1; // string x = "1";
x = x + null + null;
Console.WriteLine((x==null) ? "<null>" : x.ToString());
Regard the 1st line of the code snippet: If x is a nullable integer variable (i.e. int?) containing value 1, then you're getting the result <null> back. If it is a string (as shown in the comment) with value "1", then you're getting "1" back rather than <null>.
N.B. Also interesting: If you're using var x = 1; for the first line, then you're getting a runtime error. Why? Because the assignment will turn the variable x into the datatype int, which is not nullable. The compiler does not assume int? here, and hence fails in the 2nd line where null is added.
Because there is no difference between string.Empty and null when you concat strings.
You can pass null into string.Format as well. But you are trying to call a method on null, which would always result in a NullReferenceException and therefore generates a compiler error.
If for some reason you really want to do it, you could write an extension method, that checks for null and then returns string.Empty. But an extension like that should only be used when absolutly necessary (in my opinion).
As general: It may or may not valid accepting null as a parameter depending on specification, but it is always invalid to call a method on null.
That's and other topic why the + operator's operands can be null in case of strings. This is kinda VB thing (sorry guys) to make programmers life easier, or supposing the programmer can not deal with nulls. I completely disagree this specification. 'unknown' + 'anything' should be still 'unknown'...

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.

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