Is there a right way to retrieve a String field in SQL - c#

I have seen different ways to retrieve a string field from SQL. Is there a "right" way, and what are the differences
SqlDataReader rdr;
1. String field = (String) rdr["field"];
2. String field = rdr["field"].ToString();
3. String field = rdr["field"] As String;
Thanks!

You could also use:
int ordinal=rdr.GetOrdinal("stringField");
if (rdr.IsDBNull(ordinal))
{
return string.Empty; //Or null or however you want to handle it
}
else
{
rdr.GetString(ordinal);
}
Which if you look at the definition for SQlDataReader["field"] looks like:
public override object this[string name]
{
get
{
return this.GetValue(this.GetOrdinal(name));
}
}
Essentially this is doing the same thing, only it's type safe. What I like to do is Create my own IDataReader which wraps SqlDataReader. CSLA uses a simillar mechanism that they call SafeDataReader since it provides overloads for all the various data types which implements this pattern.
If you know the field won't be null you could leave out the isDbNull checks. Due to the verbosity I'd recommend putting this in some type of wrapper or helper class and make functions out of them.

May cause an exception if the type is not string
Is definitely wrong because that could raise an exception if the value is null.
Will assign null if it is null or if it is of type other than string
So, to be on the safe side - I would choose 3.

Keep in mind that the question interacts with your data definitions. If "field" has been defined as "Not Null" then you don't have to worry about null data and should choose #1 for readability. Similarly, if the field is nullable but you use an "IsNull" function when doing your query:
Select IsNull(Field1, '') as Field1 From DBTable Where...
then, again, you should choose #1 because you still don't have to worry about null. Of course, this assumes that you would WANT the null value to be masked by the empty string. If you want to test against null because it is an error condition then you'd have logic like:
if (nwReader.IsDBNull(nwReader.GetOrdinal("Field1")))
*throw exception or otherwise handle null condition
string aStr = (string)nwReader["field"];
This last case, however, is not really good practice. If null is an invalid value - an error condition - then you should rule it out in your DDL.
In the end, though, I always go for option #1 because I think it leads to better readability and it forces me to make my null handling explicit.

If I'm expecting a string, I'll do #1. If for some reason the field isn't a string or changes type, you'll at least know about it through the exception mechanism. (Just don't wrap it inside of a try / empty catch.)

I like the ?? operator for checking nulls (as discussed in other posts)
String field = rdr["field"] As String ?? string.Empty
This should work. If not, well its late :P, unless you actually want the result to be null. If so then I like 3.

Related

How to make a method that makes a string null

I want to make a method that gives a string (input in method) the value null. This is for my database, so that there are no 'open' values.
It needs to be something like this:
public string NulValue (string value)
{
value = null; //the string-value needs to get the value null here
return value; //returning the value
}
But this is not giving the string the value null. I think the solution is very easy, but I don't get it to work. I use WPF.
Here is where I want to use the method:
string checkcomment = TextBxComment.Text;
if (checkcomment == "")
{
NulValue(checkcomment);
}
You can not make a string anything. While strings are reference types, they are on that is designed to work like Value Type for many purposes. Do not try to learn class semantics with string. You can however set the reference to null, wich works similar to setting a value type to anything in a function.
By default functions use "call by value", wich means a copy of the Primitive Type or Reference variable is made. And you then work with that copy. In order to force a function to use call by reference (in wich the actually variable is re-used and can be modified), the ref and out keywords are used for that.
However teh whole operation makes little sense. As far as you example code shows, you want to set the reference variable to null. At wich point
myValue = null;
will always be easier to write and read then
NullValue(ref myValue);
But of course there might be some logic you have not shown us.
Properties can not be used as ref values. So if you use properties, you have to write somewhat more code.:
var temp = Instance.MyValue;
NullValue(ref temp);
Instance.MyValue = temp;
With a Database, this might be about mapping the .NET Type/Value Null to the Databases Type/value Null. Wich can be very different things.

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.

C# - Methods for null checking

What's the preferred way of checking if the value is null?
Let's say we have some entity, which has properties, which can be null (some of them or all of them).
And I wish to check this in runtime, if some property is actually null or not.
Would you use simple Entity.Property != null check in this case or would you implement a specific method, let's say like
bool HasProperty() {
return Property != null;
}
What would you choose and why?
For property values which can be null, my preference is to do the following
Have the property containing the value which can possibly be null
Have another property prefixed with Has and the rest containing the original property name which determines if the other property is non-null
Add an assert into the original property if it's accessed when null
In this example it would be
SomeType Property {
get {
Contract.Requires(HasProperty);
return _property; }
}
bool HasProperty {
get { return _property != null; }
}
The reasoning behind this is that C# does not have a standard way of describing whether or not a value can be null. There are many different conventions and techniques avalaible but simply no standard. And not understanding the null semantics around a value leads to missed null checks and eventually NullReferenceExceptions.
I've found the best way to express this is to make the null feature of a property explicit in the type itself by adding the Has property if and only if the property can be null. It's not a perfect solution but I've found it works well in large projects.
Other solutions I've tried
Do Nothing: This just fails over and over again
Using an explicit Maybe<T> or Option<T> type in the flavor of F#. This works but I find I receive a lot of push-back from developers who've never done functional programming and it leads to a rejection of the idea entirely in favor of #1.
Just check if the property itself is null, there is no need to create a method for this. Properties are really just methods that are generated by the compiler.
There is no pattern that covers this. In fact, anything you do to try and make this "easier" could be considered an anti-pattern.
"Hey, don't check if the property is null, use the Is[Property Name]Null property"
Uh, no.
I check only against null, because every nullable type does internally exactly what you described (but the internal method is called HasValue instead of HasProperty):
http://msdn.microsoft.com/de-de/library/b3h38hb0.aspx
If Property is something that isn't public, then you would need a method like HasProperty(). Also, if you implement your "nullness" in another way, it would also be good to have a HasProperty() method.
Null is not necessarily bad. I think it all depends on why you need to check for null to determine how you should check for it.
I would choose to write a separate Has* property only if the property is auto-initializing (i.e. just getting it might cause, say, an empty collection to be allocated) and it makes a performance difference. If getting the property is cheap (as it should be; in some cases you just can't help having it make a difference, though), there's no need for a superfluous Has method.
So no Has for the general case:
public string Foo { get; set; }
But in some cases, it can be a good idea:
private List<string> someStrings = null;
public List<string> SomeStrings {
get {
if (someStrings == null)
someStrings = new List<string>();
return someStrings;
}
}
public bool HasSomeStrings {
get { return (someStrings != null && someStrings.Count > 0); }
}

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).

How to tell what is passed when no value exists

For this code, how do you know that null is returned if there is no value in the querystring?
HttpContext context = HttpContext.Current;
string strValue = context.Request[name];
I'm asking because I never know what's being returned in many cases in the .NET framework when you don't get the value expected when it does not exist.
so if context.Request[name]; is called and the name doesn't exist in the querystring, how do you know it returns null or an empty string so that I can properly handle the case where it does not exist?
Use String.IsNullOrEmpty() to check for a Null or Empty string.:
string strValue = !String.IsNullOrEmpty(context.Request[name]) ??
context.Request[name] : "Some Default Value";
Or if you don't have a default value you'd like to set, you can do the check later:
if(String.IsNullOrEmpty(strValue))
{
// It's Null Or Empty
}
else
{
// It's Not
}
Update
Just saw the comment. If you're trying to figure out if referencing a key that doesn't exist in the Params collection (which is what you're using via shorthand), then check the MSDN documentation.
In this case, Params is a System.Collections.Specialized.NavmeValueCollection. The documentation is here. According to the documentation, a null value is indeed returned when a key is not found in the collection.
Therefore you don't have to use String.IsNullOrEmpty(). You could just:
string strValue = context.Request[name] ?? "Some Default Value";
If you want to set a default, or check for null otherwise.
As #Justin Niessner says, you can check the context.Request[name] for null as you read it. This is perfectly efficient and reasonable.
If you feel uncomfortable working with nulls, you can examine the collection into which name is the index.
In your example, context.Request[name] is shorthand for context.Request.Params[name]. Params is a NameValueCollection, which in turn has a property AllKeys. Assuming we're using .NET 3.5 you can then use .Contains() like so:
if (context.Request.Params.AllKeys.Contains(name))
{
// do something
}
Also, you specifically mention you're interested in the query string. context.Request[] returns not just the query string, but also Cookies, Form and ServerVariables. For the query string, use
if (context.Request.QueryString.AllKeys.Contains(name))
{
// do something
}
I think what you are asking is 'how do I know what the behaviour of this object is?' - in which case I don't know of a better answer than 'check the documentation' - in this case, HttpContext.Request is documented as being of type HttpRequest, which in turn is documented as having an Item method for which the documentation says:
If the specified key is not found, then a null reference (Nothing in Visual Basic) is returned.
What I can't immediately see is how you would light on the Item method specifically as the name of the indexer (this[]) method if you didn't know that that was a standard convention...
Request.Params is a NameValueCollection, which will return 'null' if a key does not exist in the collection.
So, if the URL was:
http://localhost
Then context.Request.Params["foo"] would be null.
Now, if the request was:
http://localhost?foo=
Then context.Request.Params["foo"] would be "".
I think this is what you are looking for.
You can do something like this using Extension Methods:
if(!Request["Name"].IsNullOrEmpty())
{
// do something with the Request["Name"] value
// OR
// You can extract the Request["Name"] into a variable and do the same with the variable
}
The ExtentionMethod look something like this:
public static bool IsNullOrEmpty(this string str)
{
return String.IsNullOrEmpty(str);
}
Thanks!

Categories