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.
Related
I have a variable that I want to change inside a function and reflex the new change in the orginal variable . I am trying to change the original variable value to Scott inside the function and then reflex that new change outside the function:
public ActionResult HomePage()
{
string name = "John";
ChangeName(name);
string newName = name ; -- This still says John
}
public static void ChangeName(string myname)
{
myname = "Scott";
}
You can do that by passing the string by reference -
public ActionResult HomePage()
{
string name = "John";
ChangeName(ref name);
string newName = name ; -- This is now Scott.
}
public static void ChangeName(ref string myname)
{
myname = "Scott";
}
However, as stated by TheSoftwareJedi in the comments, it is usually best to avoid passing parameters by reference. Instead, you should have your method return the new string, especially considering the fact that strings are immutable, so you can't really change them, you can only change the reference to point to another string.
So a better method would be something like this:
public static string GetAnotherName()
{
return "Scott";
}
A little more in depth - there are basically two kinds of types in c# (relevant to this point, at least): There are value types like enums, structs (including all primitive types such as int, bool etc') and there are reference types (basically, everything else).
Whenever you pass an argument to a method, it gets passed by value, unless you specify the ref (or out) keyword, even if it's a reference type (in that case, the reference gets passed by value). This means that when ever you are assigning a new value to the argument inside the method, you will only see it outside the method if the argument was passed explicitly by reference (using the ref or out keyword).
The main difference between reference types and value types is that when you change the properties of a reference type inside a method, you will see the new values outside the method as well, however when you change the properties of a value type inside a method, that change will not reflect to the variable outside that method.
Jon Skeet have written a fairly extensive article about that subject, and he is way better than me in explaining things, so you should probably read it as well.
To start with, I would recommend you to read about references, values and parameters passing. There is a nice summary on this theme by Jon Skeet — Parameter passing in C# and good explanation of reference concept by Eric Lippert — References are not addresses.
You should know that by default parameters are passed by value in C#, it means parameter will contain a copy of the reference passed as argument, it means assignments will only change parameter itself and won't be observable at the call site.
That's why
myname = "Scott";
Only changes value of the method parameter myname and not the outer name variable.
At the same time, we are able to pass our variable by reference with use of ref, in or out keywords. Although in and out keywords are adding excess guarantees, which are out of theme discussed, so I'll continue with ref.
You should change both declaration of your method and call site to use it.
public static void ChangeName(ref string myname)
{
myname = "Scott";
}
And it should be invoked now as
ChangeName(ref name);
This time there is no copying, so myname parameter stores the same reference as name variable and, moreover parameter and variable are stored at one location, it means changes to myname inside ChangeName method will be visible to invoking code.
To continue with, I'd like to point you to a separate, but related theme in regards of your question — Expressions and Statements and to link you to a good article about them written by Scott Wlaschin — Expressions vs statements (there is a bit of F# inside, but that's not critical).
Generally, there is nothing wrong with approach you've selected, but it's imperative, statement based and a bit too low level. You are forced to deal with references and their values, while what you really want is just to get value "Scott" from your method. This will look more straightforward and obvious, if implemented as an expression.
public static string GetName() => "Scott";
This way code is declarative and thus more simple (and short), it directly illustrates your goals.
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!
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.
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); }
}
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.