C# Workshop - Week 1 (Ch. 1 - 4) - Beginners

Started by
91 comments, last by CalebGorde 12 years, 9 months ago
Quote:Original post by RJSnow
On the side, I'm reading a different C# book, I know this isn't in the specification, but it has to deal with C#, so maybe someone can answer this.

What's the real difference between these two styles? Is one style better than the other?

Quote:
Console.WriteLine("Hello, {0}!", FirstName);


and
Quote:
Console.WriteLine("Hello, "+FirstName+" !");


It is usually better to use the first one. Using the + operator on strings builds a completely new string, because in C# strings are immutable (ie. they cannot be changed), so a new one needs to be built, and can result in reduced performance for larger strings.

In fact, the StringBuilder class is the preferred method of combining strings, as it doesn't have to create and destroy strings in memory when it is used. If you are wondering when to use these three different methods ( +operator, {0}, and StringBuilder), consider the following points:

1) It's much easier to see in the code the + operator, and it is more intuitive for quick read-throughs. For this reason, I almost always use the + operator, even though it is slightly less efficient, because the difference is rather small for most operations. After I profile my code, I can see if I need to go back and change it.

2) The format method used by Console.WriteLine and string.Format actually use a StringBuilder internally, so calling the Console.WriteLine in the first example is actually the same as using a StringBuilder. Hence the reason that the first example is "better".

Hope it all helps!
Mike Popoloski | Journal | SlimDX
Advertisement
personally, i use the sloppy "+" method,

but if you want the "best" way, then actually you dont want to use either method.

create your string before sending it to Console.Writeline. This is because it lets you do things like inspect the string in a debugger, and do other logic on it.

If you are doing anything where performance matters, then CONSIDER using string builder. I say consider, because actually doing things like what you showed in your example isnt going to be any faster with string builder, it will probably actually be slower.

where string builder IS good, however, is where you concatenate lots of strings together, such as if you had an array or something of the sort. So keep that in mind, but ultimately if you are not doing something where performance matters, dont worry about it.



Quote:Original post by novaleaf software
personally, i use the sloppy "+" method,

where string builder IS good, however, is where you concatenate lots of strings together, such as if you had an array or something of the sort. So keep that in mind, but ultimately if you are not doing something where performance matters, dont worry about it.


You are right that in a small example there is little to no difference, and that there is no reason to optimize unless a profiler tells you to, but a few things that you said strike me as rather odd.

This:
Quote:
but if you want the "best" way, then actually you dont want to use either method.

create your string before sending it to Console.Writeline. This is because it lets you do things like inspect the string in a debugger, and do other logic on it.

Where you build the string has no bearing on how you build the string. He is still going to have to pick a method of concatenation, whether he creates the string as a local variable, a class variable, a static variable, or as a method parameter. If he is just going to print out his name, why should he bother creating an extra string variable, just in case he decides he needs to "inspect" the string in the debugger?
Mike Popoloski | Journal | SlimDX
Quote:Original post by Mike.Popoloski
Quote:Original post by novaleaf software
personally, i use the sloppy "+" method,

where string builder IS good, however, is where you concatenate lots of strings together, such as if you had an array or something of the sort. So keep that in mind, but ultimately if you are not doing something where performance matters, dont worry about it.


You are right that in a small example there is little to no difference, and that there is no reason to optimize unless a profiler tells you to, but a few things that you said strike me as rather odd.

This:
Quote:
but if you want the "best" way, then actually you dont want to use either method.

create your string before sending it to Console.Writeline. This is because it lets you do things like inspect the string in a debugger, and do other logic on it.

Where you build the string has no bearing on how you build the string. He is still going to have to pick a method of concatenation, whether he creates the string as a local variable, a class variable, a static variable, or as a method parameter. If he is just going to print out his name, why should he bother creating an extra string variable, just in case he decides he needs to "inspect" the string in the debugger?


You are right also, in that simplisticly none of this really matters, but from a "best practice" perspective, were you to have a fairly compacated string being built and passed to any method (be it .WriteLine or anything else) you REALLY should get into the habbit of creating your string outside of the method call.

for example:
Console.WriteLine("Result = {0} after run {1} with extra info {2} and {3}",myArray[23].ToString(),myVariable,extraSalt1, rtfm.SuperSpicyMethodResult(2));

is an extreme example of why even using the format override isnt that great. If one of those methods returns null, you have a hard time in the debugger finding out which one. Also if you wanted to add a 5th argument, that's not supported so you will have to switch to another form of string concatination anyway.

Anyway... the short answer is do it whatever way you are most comfortable with. The long answer is to do it in the way that you are most comfortable with :)



As I said, it's a best practice, which, unlike religious texts, is meant to be taken with a grain of salt.
I guess you're right, but I have never run into such an extreme example, and I almost always validate any questionable strings with something like string.IsNullOrEmpty before I use them anyway.

Also, this is the beginner thread, so I was trying to provide him with a simple answer to a potentially long and debatable topic.
Mike Popoloski | Journal | SlimDX
Exercise 1:

class Exercise1{    public static  void Main()     {        System.Console.WriteLine ("Servet");    }}


or


using System;class Exercise1{    public static  void Main()     {        Console.WriteLine ("Servet");    }}


Thanks everyone for taking the time to help us beginners out :)
Quote:Original post by Mike.Popoloski
1) It's much easier to see in the code the + operator, and it is more intuitive for quick read-throughs. For this reason, I almost always use the + operator, even though it is slightly less efficient, because the difference is rather small for most operations. After I profile my code, I can see if I need to go back and change it.

There are other reasons to avoid using operator+ to concatenate strings. As an example, you may need to perform cultural specific formatting, which string.Format can handle. There are also security concerns, as the usage of operator+ to concatenate strings will leak into other areas (hello SQL), while parameterized strings will tend to promote good practices, such as parameterizing SQL queries.
Quote:2) The format method used by Console.WriteLine and string.Format actually use a StringBuilder internally, so calling the Console.WriteLine in the first example is actually the same as using a StringBuilder. Hence the reason that the first example is "better".

Also note that when you allocate a string builder (or they allocate one, as the case may be), a hint is passed to indicate the expected size of the string that will be the end result. This further reduces the number of heap allocations required to produce the end string. In the case of string.Format: StringBuilder builder = new StringBuilder(format.Length + (args.Length * 8));

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

Quote:Original post by glassflakes
Exercise 1:

*** Source Snippet Removed ***

or


*** Source Snippet Removed ***

Thanks everyone for taking the time to help us beginners out :)


The question you are asking is "should we use the using" clause

Generally, most people lean towards the using clause. This is helpful if you are familiar with all the classes in your namespaces, but for beginning, i think it might be helpful to explicitly resolve the classes, as it gives you a better degree of familiarity not only with what the various namespaces are, but what other classes are "close" to the one you want.

For example, System.Collections ... if you got used to the "using" clause, you might not realize the .Generics namespace that lives under there... (this is a dumb example because visual studio express auto uses System.Collections.Generics, but you get the idea)

A real example, that is almost as stupid, is when I just started using Visual Studio Orcas, and typed in System.Collections.Generics. and I see a new collection called a HashSet<T>

but regardless to what i just rambled, the best practice is:
if it's a class you use a lot in your sourcecode.cs file, then add the using clause on top.

if you have namespace collisions, then also use the global:: namespace keyword (a collision is, if you have two classes with the same name, but in different namespaces, it lets you differentiate between the two.

for more info on the global namespace, check out "How to: Use the Namespace Alias Qualifier (C# Programming Guide)" in MSDN
As for me, I always add the namespace, as it makes the code more clean and readable, which is almost always the best possible thing. I never add them myself, though. I let the IDE do it for me whenever it can't resolve a name. I don't think it would help a new user out. I can't really think of any good reasons, and the ones you listed sure don't make much sense. :)
Mike Popoloski | Journal | SlimDX
<opinion>
For using directives, I generally follow a balance between the "make your code readable" and "bring in only what you need" guidelines. That is, if a particular namespace contains types that I plan on using a lot in the file, I will type out a using directive for it. If I need a type from a namespace, but only once or a relatively small number of times, I will omit the directive and simply type out the fully qualified name of the type. If I ever start using the type enough to warrant a using directive, I'll refactor the code to do so (I've found it's easier to refactor away fully-qualified names than to add them).

Conflicts are sometimes resolved via namespace aliases, especially for deep nested namespaces.
</opinion>

Namespaces aliases, for those who do not know, are a way to assign a (ideally shorter) alias to a namespace for a particular file. For example, I often use
using DX = SlimDX;using D3D = SlimDX.Direct3D;using D3D10 = SlimDX.Direct3D10;

at the top of my files that talk directly to Direct3D (via SlimDX). This allows me to refer to a particular type, say SlimDX.Direct3D10.Texture2D as D3D10.Texture2D, which prevents a conflict with my own Texture2D type (as well as helping prevent long lines).

This topic is closed to new replies.

Advertisement