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

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.

Related

A little bit of string cast

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.

"string s = null" is technically incorrect?

Please let me know if this is in the wrong place, or let me know a better place for it.
This question is not about the syntax, more the idea behind it.
I would like to know what null is essentially, or isn't as the case may be
First off, I just want to clarify exactly what null is. By my understanding, null is
technically nothing. So the statement
string s = null;
is technically incorrect? You are assigning a variable no value but a variable can't not have a value? Am I correct in thinking this?
My idea of null is that it's kind of like thinking, "If I go and get a drink of water, I will need a cup to put the water in". null is the space in which the data will be placed in, but the space doesn't exist yet. Following this idea:
string s = "";
would be more appropriate, no? And along this thought (though a bit less confusing)
int n = 0;
follows the same idea, where 0 is a value, but the value of 0 is nothing?
The original line of code is quite valid. In C#, any reference type variable can have no value, i.e. it refers to no object. null is quite different to an empty string. Consider a variable of some other type, e.g. Form. What would be the equivalent of an empty string then? A null in C# is basically the same as a NULL in a database.
Value types are a but different. Because reference type variables contain a reference, it is possible for them to refer to no object. Value type variables, on the other hand, contain a value and so cannot be null. A struct or enum is a value type and a class or delegate is a reference type. So, if a variable on the stack contains the value zero then, for a reference type that means no object, i.e. null, and for a value type that means the default value for that type, e.g. zero for numbers, false for bool and DateTime.MinValue for DateTime.
C# references are basically tarted-up pointers. Just as in C/C++ a pointer can be null to point to no object, so a C# reference-type variable can be null to refer to no object. In the case of strings, an empty string is an object and is very different to null. An empty balloon is still a balloon and very different to no balloon at all.
Your confusion likely lies in the difference between reference types and value types.
void Foo() {
string s = null;
}
This does not create a string. Instead, s is a reference to a string. However, s is currently referring to (or pointing to, in C terminology) nothing.
s ---> [nothing]
Now when we do this:
s = "Stack Overflow";
we are making s refer to that string. s itself doesn't contain the string.
s ----> "Stack Overflow"
Note that "" itself is a string, and does exist
s ----> ""
Strings are actually a bad example because of string interning.
Value types on the other hand line up with your confusion.
An int for example, must have a value. If you don't assign it one, it will (generally) take the default value of 0.
See more:
Value Types and Reference Types
This is not wrong as much as it is redundant because null is the default value of string
as int num = 0 is redundant because 0 is the default value of int
If you need to initialize your string then you should go for string s = "" or my personal favorite string s = string.Empty
Null means nothing. 0 is a value, but null means that there is no value. Actually in C#:
string s=null;
means that instance of the class string is null and has no value.
Imagine string s is just a variable pointing to a place in memory which was allocated for you.
string s = null; Is allocating a variable but it is not pointng to a place in your memory.
string s = "; micht be the same but it is pointing to a slot in your memory containing a iteral with an empty string.
I hope that made the problem a bit more clear.

Get type using reflection

I am trying get type of property of my class by using of reflection but its returning my only RuntimePropertyInfo - as a name of a type.
I have object MyObject actualData - it contains property - "name" as string and "Item" as my type DatumType
When I am debugging I can see, that actualData has 2 properties, first one is type of string and second one is DatumType, but when I use this:
string typeName = actualData.getType().getProperty("Item").getType().Name - it returns me RuntimePropertyInfo, not DatumType
Can you see what am I doing wrong? I am using C# - .Net 4.0.
Thanks a lot!
You're getting the type of the PropertyInfo object getProperty() returns. Try
string typeName = actualData.getType().getProperty("Item").PropertyType.Name;
If you want the type of the value currently assigned to the object via the PropertyInfo object, you could call:
string typeName = actualData.getType().getProperty("Item").GetValue(actualData, null).GetType().Name;
But in that case you could also simply call:
string typeName = actualData.Item.GetType().Name;
The
actualData.getType().getProperty("Item")
retrieves something of type PropertyInfo.
If you then ask for its type:
actualData.getType().getProperty("Item").getType()
you get exactly what you observe you get.
I suspect this last getType() is not necessary then.
Edit: someone has downvoted this answer which is unfair imho. The question is "Can you see what am I doing wrong?" and the answer of being one getType too far is a correct one. Finding PropertyType in PropertyInfo is then easy if the asking person knows what he is doing wrong.
To the person who downvoted this answer: please at least leave a comment next time you downvote something. Stackoverflow makes sense only if we learn from each other, not just bash everyone around.
GetType() return always the type of the current object, not the pointed object.
In your case, consider using string typeName = actualData.getType().getProperty("Item").PropertyType.Name

C# null - is it an object

When I was writing C# code a few days ago I noticed that the compiler complained that I had to cast null to a specific object.
Does this mean that null is simply an uninstantiated version of the type? Or is it a singleton value of a Null class like Java (even though it has special privileges)?
EDIT: an example of the code giving the error would be:
public String duplicate(String toDuplicate)
{
return toDuplicate + toDuplicate;
}
public String duplicate(int? toDuplicate)
{
String asString = toDuplicate.toString();
return asString + asString;
}
public static int Main(string[] args)
{
//This needs to be cast:
duplicate(null);
//To:
duplicate((string)null);
}
The reason I commented on null in Java was after reading this:
There is also a special null type, the
type of the expression null, which has
no name. Because the null type has no
name, it is impossible to declare a
variable of the null type or to cast
to the null type. The null reference
is the only possible value of an
expression of null type. The null
reference can always be cast to any
reference type. In practice, the
programmer can ignore the null type
and just pretend that null is merely a
special literal that can be of any
reference type.
Found here: Is null an Object?
I get the error you refer when i have overloaded methods and the compiler can't resolve which method to call at compile time. Is that it?
According to the MSDN description:
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. Ordinary value types cannot be null. However, C# 2.0 introduced nullable value types.
null is the "uninstanciated reference" for any type. It is not a value. null has no defined type.
No - the null is just a literal for the null reference.
The reason you need to "cast" it in this way (I put the word cast in quotes because you are not really casting an instance of anything), is purely to help the compiler resolve which overload of a method you are calling, or the method you are calling even exists.
In your example, you need to specify that you are calling the method "duplicate" that takes a single string argument. If you omit the cast, then the compiler only knows that the method you intended to call is called "duplicate" and has a single argument, but can't tell what type the argument is - did you mean to call duplicate(string) or did you mean to call duplicate(some other type)? Should it compile, or should it error telling you the method you are trying to call does not exist?
You will also get the same issue if you had a duplicate(byte[]) defined, because now your call is ambiguous without the explicit cast.
No its not an object. null is the default value of reference-type variables. Ordinary value types cannot be null. but there is another set called nullable types.
You are probably referring to the fact that the following leads to a compiler error:
int? nullableInt = (somecondition) ? value : null;
Indeed you need to add a cast here:
int? nullableInt = (somecondition) ? value : (int?)null;
Even though I'm not able to explain this in detail, I'd suspect the following:
int? is actually a short form for Nullable<int>, so it is basically an object instance. When assigning an int value to nullableInt, a property of Nullable<int> will be set internally. Directly assigning null would also be ok.
The conditional assignment however, would return two different types: int in case somecondition is true and object (null) otherwise.
Now the compiler doesn't know how to handle this, as the ternary operator needs to return values of the same type. So you need to specify the desired "type for the null value".
Sorry if this is not a very deep technical explanation - I'm sure there's somebody who can elaborate this better, but it might help understand this better.

Why can't I use the as keyword for a struct?

I defined the following struct:
public struct Call
{
public SourceFile caller;
public SourceFile callee;
public Call(SourceFile caller, SourceFile callee)
{
this.caller = caller;
this.callee = callee;
}
}
Later, I assign it to the Tag property of another object:
line.Tag = new Call(sf1, sf2);
But when I try to retrieve the Tag property like so,
Call call = line.Tag as Call;
Visual Studio gives the following compile-time error:
The operator as must be used within a
reference type or nullable type
What is the meaning of that? And how can I solve it?
Some of the existing answers aren't quite right. You can't use non-nullable types with as, because the result of as is the null value of the type if the first operand isn't actually of an appropriate type.
However, you can use as with value types... if they're nullable:
int a = 10;
object o = a;
int? x = o as int?; // x is a Nullable<int> with value 10
long? y = o as long?; // y is a Nullable<long> with the null value
So you could use:
Call? call = line.Tag as Call?;
Then you can use it as:
if (call != null)
{
// Do stuff with call.Value
}
Two caveats though:
In my experience this is slower than just using is followed by a cast
You should seriously reconsider your current Call type:
It's exposing public fields, which is generally poor encapsulation
It's a mutable value type, which is almost certainly a mistake
I would strongly suggest you make it a class instead - at which point this problem goes away anyway.
Another thought: if the tag should always be a Call, then it's better to cast it:
Call call = (Call) line.Tag;
That way, if the data doesn't match your expectation (i.e. there's some bug such that the Tag isn't a Call) then you get to find out about it early, rather than after you've potentially done some other work. Note that this cast will behave differently depending on whether Call is a struct or a class, if Tag is null - you can cast a null value to a variable of a reference type (or a nullable value type), but not to a non-nullable value type.
A struct is a value type, so it cannot be used with the as operator. The as operator must be able to assign a value of null if the cast fails. This is only possible with a reference type or a nullable value type.
There are a couple ways to solve this, but your best bet is to change your Call type from a struct to a class. This will essentially change your type from a value type to a reference type, which allows the as operator to assign a value of null if the cast fails.
For more information on value types vs. reference types, this is a decent article. Also, have a look on MSDN:
value types
reference types
as-operator
nullable types.
From the C# Spec
§7.10.11 The as operator is used to
explicitly convert a value to a given
reference type or nullable type. Unlike a cast expression
(§7.7.6), the as operator never throws
an exception. Instead, if the
indicated conversion is not possible,
the resulting value is null.
References and nullable types can be null. Stucts are value types so they can't be null.
Call? call = line.Tag as Call?;
It's a limitation of C#. If the type were a reference type, then if the cast failed it would simply return 'null', but since it's a value type, it doesn't know what to return when the cast fails.
You must replace your use of as with two: 'is' and 'as'
if (line.Tag is Call) {
call = (Call)line.Tag;
} else {
// Do whatever you would do if as returned null.
}
What is the meaning - As stated, structures are value types.
How can I solve it - Change it to
Call call = line.Tag;

Categories

Resources