A little bit of string cast - c#

Update:
When a database returns a value through the scalar, it will always be an object. So when the value is returned you should have a preconceived notion of what the type will be. Why would you use ToString(); when you you have a SELECT which passes two parameters.
As if it doesn't exist it will always throw a null. So in my refactor I believed the as would be the proper approach. As ToString() will throw an error --- So what form of cast is it comparable to?
I've got some code I'm maintaining, but in apart of my refactor I came across a ToString() attached to an ExecuteScalar. My question would be, does the usage of ToString() equate to:
(string)command.ExecuteScalar();
Or would it represent this:
command.ExecuteScalar() as string;
Obviously the as string would fail gracefully, where the cast (string) would actually fall into an InvalidCastException. So when you call:
command.ExecuteScalar().ToString();
Which method of casting is it attempting to do?

No, it doesn't mean either of those - it simply means calling ToString() on whatever the value is.
In particular, if the value is not a string, it will convert it to a string anyway - whereas string would fail with InvalidCastException and the as would return null.
So for example:
object x = 10;
string a = x.ToString(); // "10"
string b = x as string; // null
string c = (string) x; // Bang
Of course, ToString() can still throw an exception too - most obviously if the target of the call is a null reference.
Personally, I would suggest using a cast if you know what the result type should be - although the result of ExecuteScalar is more commonly a numeric value (e.g. a count) rather than a string.
Yes, that means an exception will be thrown if you're wrong - but if your query isn't doing what it's meant to anyway, then stopping due to an exception may well be better than going ahead with a bogus view of the world. (See my blog post on casting vs as for more on this attitude.)

Neither, because Object.ToString() will returns you a string representation of the object. Regardless whether the query returns a varchar or int.

If command.ExecuteScalar() returns null then it would be something like null.ToString() which will break your production code.
also (string)command.ExecuteScalar() can break your code.
I would suggest to use below line
var result = command.ExecuteScalar() as string;
if(result != null)
{
//your code
}

Let's think about it for a bit.
When you do command.ExecuteScalar() you get back and object in a lot of cases based on the provider you get an int.
What happens is the order of operations triggers
Command.ExecuteScalar() gets and object back.
We are assuming he is an int for the excercise we get that int back.
To String gets called which is defined in the int32 object itself.
You get back the string that was determined inside.
For the most part toString is not meant to throw an exception if no one has implemented in the chain you just get the object type back which is the implementation on the object.
With that said in the case of the int it would probably be the one above. Note if execute scalar returns null to string will error out since null is not an object.
Hope that helps.
P.S. If you tell me the object type of ExecuteScalar i can give you a better answer.

Related

How to test a null value variable if it's a string?

Is it possible to test if a variable is defined as a string if the value inside it is null?
If I write:
string b = null;
bool c = b is string;
Then c will be false because is looks at the content, which is null and not a string.
If I write:
string b = null;
bool c = (b.GetType() == typeof(string));
Then it crashes because s is null and you can't call GetType() on a null value.
So, how can I check b to find out what type it is? Some kind of reflection maybe? Or is there any simpler way?
Edit 1: Clarification of the question!
I was a bit unclear in my question and that was my fault. In the example it looks like I'm trying to test the content of the variable. But I want to test the variable itself without looking at the content. In the code examples given I can see that b is a string, but what if I don't know if b is a string and just want to test the variable s to see if it is a string or not.
So, how can I know what type the variable is defined as? As in this example, but x is an unknown variable that might be defined as a string and it might be null as well (since it might be null this example won't work).
bool c = (x.GetType() == typeof(string));
Edit 2: The working solution!
Thanks to all the answers given I was able to solve it. This is how the working solution became. I first created a help function to test the defined type of a variable that works even if the value is null and it doesn't point to anything.
public static Type GetParameterType<T>(T destination)
{
return typeof(T);
}
Then I can just call this function and test my "suspected string" and find out if it really is a string or not.
// We define s as string just for this examples sake but in my "definition" we wouldn't be sure about whether s is a string or not.
string s = null;
// Now we want to test to see if s is a string
Type t = GetParameterType(s);
b = t == typeof(string); // Returns TRUE because s has the type of a string
b = t is string; // Returns FALSE because the content isn't a string
This is just what I wanted to find out!!! Thank you all for squeezing your brains...
You cannot check the type of null because null has no type. It doesn't reference anything at all, therefore there is nothing that C# can look at to find out the actual type.
(Everyone else seems to be answering the question "How can I tell if a string reference is null or empty - but I think the question is "how can I tell if the underlying type of a null reference is string...)
There might be a way to fiddle it though - you might be able to use a generic method as mentioned here:
.NET : How do you get the Type of a null object?
(That link was posted by someone else - not me - as a comment to your original post!)
So you want to know if there is a direct method to check of an object type whose value is set to NULL
In The simple word the answer is NO.
A null reference does not point to any Storage Location, so there is no metadata from which it can make that determination.
Although if you already know it is of type String , you can use following two functions for checking null values
String.IsNullOrWhiteSpace(stringObject);
and
String.IsNullOrEmpty(stringObject)
The best that you could do to set a value to unknown type is use
Convert.ChangeType
e.g. as given in .NET : How do you get the Type of a null object?
public void GetObjectValue<T>(out T destination)
{
object paramVal = "Blah.Blah.";
destination = default(T);
destination = Convert.ChangeType(paramVal, typeof(T).GetType());
}
The type of T can be inferred, so you shouldn't need to give a type parameter to the method explicitly.
Here it is
String.IsNullOrEmpty(s);
If you want to tell whether the actual value is a string, you can't do that with null, as null doesn't have a type.
So it seems you want to determine the actual type of the variable (the one it was declared as):
If the variable is of type string, then you know it at compile time (you declared it as string, after all).
If the variable is generic (like in generic types or a generic method), you can test it via typeof(T), assuming T is your type parameter.
If you got the variable as object though (e.g. as argument of a method), then there is no way to determine its original type if its value is null.
Use the String.IsNullOrEmpty method to check it.
string b = null;
bool c = String.IsNullOrEmpty(b);
See this MSDN link for further details.
IsNullOrWhiteSpace(variableName)
string.IsNullOrEmpty()
var.Trim().Length < 1
The third one is the one I personally use, as it is version-independent.

Why does integer.equals(string) give false when both contain the same value, but does not throw type mismatch exception?

I have code where I get a string as input, and I compare it with an integer.
I saw that integer variable also has an Equals function that accepts a string parameter.
I have used it directly thinking it will typecast it.
It did not give any compile time or runtime error, but it always gives a false result.
For example,
int sessionId = 1;
string requestId="1"
return sessionId.Equals(requestId);
sessionId.Equals(requestId) always gives false.
Why is the reason for such behavior? If there is a reason, why are they allowing it run without error?
Integers and strings are always different, and thus "1".Equals(1) returns false.
It compiles because object.Equals(object other) takes an object as the right side, and thus accepts any type.
The reason why this happens is that a string "0" is not the same as 0, so it returns false.
Why is such behavior supported? Because the Equals method allows you to pass an object as a parameter, and a string is in an object, so you are "allowed" to do it. As you have found, it's not very useful in this case.
To solve your problem either get a string representation of the integer, or parse your string to an integer, then compare.
E.g. Try
return (sessionId.ToString() == requestId);
or
return (sessionId == int.Parse(requestId));
If you choose the later you may need to consider if the Parse could fail and how you might handle that.
Yes, Equals takes any type on the right side because it is requires an object. But inside the function it requires the same type as the left side. IMHO there's no need to throw an exception for type mismatching because one only wants to know about equality of two types.
Decompiled Equals of int:
public override bool Equals(object obj)
{
return obj is int && this == (int)obj;
}
If someone shows you a car and a banana, and asks whether they are the same thing, would you throw a temper tantrum because a car is a vehicle and a banana is a fruit, or would you simply say "no, they are not the same thing"?
In many languages, trying to compare an integer and a string will yield a compiler error, because the compiler knows that the integer and the string cannot possibly be the same thing and thus any code that tried to compare them would almost certainly be erroneous. On the other hand, when you say sessionId.Equals(requestId), the compiler knows that you are asking that requestId be passed to the Int32 override of Equals. Since that override can accept a reference to any kind of heap object, it has no problem passing the string "1". That method in turn knows that it was given something which isn't the same as an Int32 with the value 1. It doesn't know that the calling code can't possibly supply anything that would match an Int32; all it knows is that the particular value isn't the same, and because the value isn't the same it perfectly happily returns false.
Shouldn’t we be using String.Compare for string comparison and forget about Equals?
I did have the same problem and I believe the function Equals should throw an exception. In my case, I have been comparing a string with a Boolean.
The discussion by now went wrong way. This is my view:
If a comparison between objects belonging to two different classes always returns false, then they do not need to be compared in the first place.
If there is a need to have a function that bypasses type checking, there should be one. However, having the function Equals positioned as a recommended method for string comparison and in the same time introducing the possibility of unneeded bugs (which may sit in your program for eternity) is a kind of irresponsible.
Moreover, it is extremely misleading that the function call String.Equals(string1, string2, StringComparison. xxx) also accepts non-string arguments. Thus not only string1.Equals(string2).
If that is by design, then it is a poor design.

Is using "as" in C# a safe way of casting?

I am wondering if using the keyword "as" in the following code is a safe way (i.e. won't blow up) of casting in C#:
public void abc(ref Object dataSource)
{
DataTable table = dataSource as DataTable;
}
Is there a safer way of casting?
It won't blow up... but that doesn't necessarily mean it's safe.
Typically when I use a cast for a reference conversion, it's because I really, really think that the execution-time type is the one I'm specifying. If it's not, that indicates a bug in my code - and I'd rather that manifested itself as an exception.
If you've got bad data in your system, then continuing as if everything was fine is the dangerous path, not the safe path. That's the way that as will take you, whereas a cast would throw an InvalidCastException, aborting whatever you're doing before you get the chance to cause mayhem with the bad data.
as is good if it's valid for the object not to be of the given type - if it doesn't indicate a bug. You almost always see the pattern of:
Foo x = y as Foo;
if (x != null)
{
...
}
See MSDN for more details about what as does.
Note also that you probably don't want to use ref in your method. See my article on parameter passing for more details. Most of the time if I see people using ref a lot, it's because they don't understand what it really means :)
It depends what you mean by "safe". Ask yourself which is safer: an appliance with a circuit breaker, or one built without it? The one without a fuse is more likely to finish washing your clothes, but it's also more likely to burn your house down.
As you probably know, there are two main ways to do explicit casting in C#:
foo = (MyType)myObject; //Cast myObject to MyType or throw an error
foo = myObject as MyType; //Cast myObject to MyType or set foo to null
The difference is that if the runtime doesn't know how to cast myObject as MyType, the first line will throw an exception, while the second will only set foo to null. This would happen if the object living in myObject isn't a MyType, or if there's no explicit cast to MyType from whatever myObject is.
So which one is safer? Well, if "safe" means "won't throw an exception if the cast is invalid," then the as form is safer. If the casting fails, (MyType)myObject will blow up immediately, but myObject as MyType will only blow up if you try to do something to foo that you can't do to null (such as calling foo.ToString()).
On the other hand, sometimes throwing an exception is the safest thing to do. If you have a bug in your code, you probably want to know right away. If myObject is always expected to be a MyType, then a failed cast means there's a bug somewhere. If you carry on as though the casting worked, then all of a sudden your program is working with garbage data! It might blow up further down the line, making debugging difficult, or - worse - it might never blow up at all, just quietly do things you didn't expect. That could cause all kinds of havoc.
So neither form is inherently safe or correct, they're just useful for different things. You would use the myObject as MyType form if:
You don't know for sure what type myObject is
You want to do something with myObject, but only if it's of type MyType
myObject could be something other than MyType, and it won't mean there's a bug
One example is when you have a collection of different WebForm controls, and you want to clear all the TextBoxes among them:
foreach (var control in controls)
{
var textbox = control as TextBox;
if (textbox != null)
{
//Now we know it's a TextBox, so we know it has a Text property
textbox.Text = string.Empty;
}
}
This way, your TextBoxes get cleared out, and everything else gets left alone.
DataTable table = dataSource as DataTable;
Using as will return null if the cast is unsuccessful, so no it won't blow up. - that means you will have to handle the case that table is null in the rest of your code though.
as won't blow up, but if the cast fails, the variable will be set to null. You need to check for that case.
DataTable table = dataSource as DataTable;
if (table == null)
{
// handle case here.
}
It won't throw an exception, if that is what you mean by "safe". However, if the cast fails, table will be null.
DataTable table = dataSource as DataTable;
Does not throw an exception if the cast fails. Will be null instead.
DataTable table = (DataTable)dataSource;
Will throw an exception if the cast fails.
It's safe in that regard, however if it is possible for the cast to fail, then add a null check to handle it.
It is a safe way to cast in the fact that it won't cause an exception. However, it can cause hidden bugs if you are not careful.
When using as, if the cast fails then the resulting variable is null. If you don't check for this then you will later get a NullReferenceException when you attempt to access the variable, and it will be less clear on why it's failing (e.g. is it null because the cast failed or did something else later cause it to be null)
The 'as' operator won't throw an exception if the cast is invalid. It just returns null. The () approach will throw an exception. So to answer your question, it is the safest way.
Here is essentially the way you need to go about it:
if( x is MyType )
{
MyType y = (MyType) x;
}
or
MyType y = x as MyType;
if( y != null )
{
// Do stuff
}
Depends what you're trying to do:
DataTable table = dataSource as DataTable;
if (table != null) ...
means "dataSource might be a DataTable and I'm going to check it's not null."
DataTable table = (DataTable) dataSource;
means "dataSource should definitely be a DataTable and something's badly wrong if it's not".
The difference between using as and a normal cast is that if the cast can't be performed (because the object isn't the right type), the as operator will return null. A normal cast will throw an exception.
So they're both "safe" - they just have different behaviors when the cast can't be successful.
It's safe in the sense that it will get the job done if dataSource can be casted as a DataTable. But if you are worried about it not casting successfully, you can first check if dataSource.GetType() is equal to the Type you are trying to cast it to.
If you use as, there won't be a runtime InvalidCastException, but table may be null, so you need to check for that.

What is the difference in string.Equals("string") and "String".Equals(string)?

Is there any difference in following two lines of code that compares the string values.
string str = "abc";
if(str.Equals("abc"))
and
if("abc".Equals(str))
in the first line I am calling the equals method on string variable to compare it with string literal. The second line is vice versa. Is it just the difference of coding style or there is a difference in the way these two statements are processed by the compiler.
The only difference is that, in the first case, when you do:
str.Equals("abc")
If str is null, you'll get an exception at runtime. By doing:
"abc".Equals(str)
If str is null, you'll get false.
The difference is that in the second example, you will never get a NullReferenceException because a literal can't be null.
To add to the other answers: the static string.Equals("abc", str) method always avoids triggering a null reference exception, regardless of which order you pass the two strings.
As mmyers said, you the second example will not throw a NullReferenceException and while allowing the program to "appear" to run error free, may lead to unintended results.
Yes, the way the compiler processed the statements is different. The function equals for String in most languages follows the same guidlines. Here is a semicode:
override def Equals(that:String):Boolean //Should override Object.Equals
if(that==null) return false
for i from 0 to this.length
if(!this(i).Equals(that(i))) return false
return true
Normally, the method will fisrt check that that IS a String, and that this and that have the same length.
You can see, as others pointed out, that if that is null the method returns false. On the other hand, the method is part of of String so it cannot be called on null. That is why in your exampleif str is null you will get a NullReferenceException.
That being said, if you know both variables are non-null Strings of the same length, both statements will evaluate to the same in the same time.

String casts in .NET

Why is there so may ways to convert to a string in .net? The ways I have seen are .ToString, Convert.ToString() and (string). What is the Difference.
Convert.ToString(obj)
Converts the specified value to its equivalent String representation. Will return String.Empty if specified value is null.
obj.ToString()
Returns a String that represents the current Object. This method returns a human-readable string that is culture-sensitive. For example, for an instance of the Double class whose value is zero, the implementation of Double.ToString might return "0.00" or "0,00" depending on the current UI culture. The default implementation returns the fully qualified name of the type of the Object.
This method can be overridden in a derived class to return values that are meaningful for that type. For example, the base data types, such as Int32, implement ToString so that it returns the string form of the value that the object represents. Derived classes that require more control over the formatting of strings than ToString provides must implement IFormattable, whose ToString method uses the current thread's CurrentCulture property.
(string)obj
It's a cast operation, not a function call. Use it if you're sure that the object is of type string OR it has an implicit or explicit operator that can convert it to a string. Will return null if the object is null AND of type String or of type which implements custom cast to string operator. See examples.
obj as string
Safe cast operation. Same as above, but instead of throwing an exception it will return null if cast operation fails.
Hint: Don't forget to use CultureInfo with obj.ToString() and Convert.ToString(obj)
Example:
12345.6D.ToString(CultureInfo.InvariantCulture); // returns 12345.6
12345.6D.ToString(CultureInfo.GetCultureInfo("de-DE")); // returns 12345,6
Convert.ToString(12345.6D, CultureInfo.InvariantCulture); // returns 12345.6
Convert.ToString(12345.6D, CultureInfo.GetCultureInfo("de-DE")); // 12345,6
Convert.ToString(test); // String.Empty, "test" is null and it's type
// doesn't implement explicit cast to string oper.
Convert.ToString(null); // null
(string) null; // null
(string) test; // wont't compile, "test" is not a string and
// doesn't implement custom cast to string operator
(string) test; // most likely NullReferenceException,
// "test" is not a string,
// implements custom cast operator but is null
(string) test; // some value, "test" is not a string,
// implements custom cast to string operator
null as string; // null
Here is an example of custom cast operator:
public class Test
{
public static implicit operator string(Test v)
{
return "test";
}
}
.ToString() can be called from any object. However, if the type you call it on doesn't have a good implementation the default is to return the type name rather than something meaningful about the instance of that type. This method is inherited from the base Object type, and you can overload it in your own types to do whatever you want.
(string) is a cast, not a function call. You should only use this if the object you need already is a string in some sense, or if you know there is a good implicit conversion available (like from int). This will throw an exception is the object cannot be converted (including when the object is null)
as string is another way to write (string), but it differs in that it returns null rather than throwing an exception if the cast fails.
Convert.ToString() attempts to actually convert the argument into a string. This is the best option if you don't really know much about the argument. It can be slow because it has to do a lot of extra work to determine what kind of results to return, but that same work also makes it the most robust option when you don't know very much about the argument. If nothing else is available, it will fall back to calling the argument's .ToString() method.
String.Format The string class' .Format method can also be used to convert certain types to strings, with the additional advantage that you have some control over what the resulting string will look like.
Serialization This is a little more complicated, but .Net includes a couple different mechanisms for converting objects into a representation that can be safely stored and re-loaded from disk or other streaming mechanism. That includes a binary formatter, but most often involves converting to a string in some format or other (often xml). Serialization is appropriate when you want to later convert the your string back into it's originating type, or if you want a complete representation of a complex type.
Convert.ToString() will return an empty string if the object is null .ToString and (String) will throw an exception. Convert.ToString will internally call .ToString() if the value is null it will return an empty String.
object.ToString() is the most basic way of retrieving a string representation of an object, and can be specifically implemented by the object.
Convert.ToString() expands on that and provides some specific overloads for primitive types (char, byte, int, double, etc.) that allow for some more type-specific functionality (like base conversion, for example)
(string) is a casting operator, and will only work if the type is either a string or has an implicit or explicit operator that can convert it to a string. Otherwise you'll get an InvalidCastException
Don't forget as string
ToString() is a method of object, and it will always work on a non-null reference, so you'll get something, but whether that something is what you want, is a different story.
Convert.ToString() will yield the same result in most cases, but isn't as flexible as Object.ToString() as you can't pass custom formatting rules.
(string) will cast your object to string, and if it isn't a string then you'll get an InvalidCastException().
Think.
ToString is a virtual method, and each type can implement it however it wants. Also System.Object provides default implementations so that it always succeeds.
Convert.ToString works only with nulls as well and allows you to use IFormat provier as noted in the comment.
Casting to string requires object to implement casting operator. Again, types can implement it however they like, but most types do not, so you may get an exception here.
Use .ToString as your best option.
.ToString() is an instance method which asks the object for its string representation. When the object is null, this will throw a exception.
(string) is a cast to the string type, which isn't a very good idea in most cases except for simple data types, since it can break (throw an exception) when it's null or an invalid cast
Convert.ToString() does a bit more checking than a simple cast, giving a more robust alternative to the cast. It will return the empty string when the object is null.
Not to nitpick but null is a valid value for a String object. Therefore (string) null does not throw any exceptions. Try it for yourselves:
using System;
namespace Test
{
class Program
{
public static void Main(string[] args)
{
string s = (string) null;
Console.WriteLine(s);
}
}
}

Categories

Resources