MSDN says we need to convert StringBuilder object to string, but StringBuilder works fine?
Why should we convert?
string[] spellings = { "hi", "hiii", "hiae" };
StringBuilder Builder = new StringBuilder();
int counter = 1;
foreach (string value in spellings)
{
Builder.AppendFormat("({0}) Which is Right spelling? {1}", counter, value);
Builder.AppendLine();
counter++;
}
Console.WriteLine(Builder); // Works Perfectly
//Why should i use tostring like below
Console.WriteLine(Builder.ToString());
// Does it make any difference in above two ways.
Console.ReadLine();
These two calls use different Console.WriteLine overloads: WriteLine(Object) and WriteLine(String).
And the WriteLine(object) overload calls "... the ToString method of value is called to produce its string representation, and the resulting string is written to the standard output stream." (msdn)
Edit
The only difference here I can see is:
StringBuilder sb = null;
Console.WriteLine(sb); // prints terminator
Console.WriteLine(sb.ToString()); // throws NullReferenceException
In that specific example, both work fine, because Console.WriteLine will call the ToString() for you, on anything you pass it. The following also works:
Console.WriteLine(3); //called with an int;
Console.WriteLine(DateTime.Now);
Console.WriteLine(new {}); //called with an object
However, since the StringBuilder is not a string, (but an object that can make a string for you), you cannot pass it to a method that expects a string, i.e.
public void PrintMe(string value)
{
Console.WriteLine(value);
}
StringBuilder sb = new StringBuilder();
PrintMe(sb); // this will not work
Both lines of code to write to the console are doing the same thing in a different way. The second is more obvious though.
Console.WriteLine(Builder); uses the overloaded WriteLine() method that takes an object. As mentioned here the ToString() method will be called on the Builder:
'If value is null, only the line terminator is written. Otherwise, the
ToString method of value is called to produce its string
representation, and the resulting string is written to the standard
output stream.'
In the second line Console.WriteLine(Builder.ToString()); you are calling the ToString() method explicitly. This is preferable because it is immediately apparent to a developer what the code is doing.
this is from code-behind on a web form. i appended several times to my StringBuilder and accidentally did
return "[" + sbFinalContents + "]";
and i haven't had any trouble with it. i accidentally left off the ToString() part and i didn't even notice for a few days. any idea why this does not blow up?
StringBuilder.ToString Method (.net 4.) : "You must call the ToString method to convert the StringBuilder object to a String object before you can pass the string represented by the StringBuilder object to a method that has a String parameter or display it in the user interface."
technically, i'm not doing either one (i'm just returning a string), but i'm still surprised it hasn't failed.
Related
Is it possible to define type and value of variable in parameter of method (existing types string, int, double or your own types)?
Reason for that is to define variable only at parameter not out of function, like other variable.
Example just for test:
public string test(string x){ return x; }
test(new StringBuilder{"New created string!!!"}[0].ToString()));
above will just return first char, we want to return hole string (or any other type).
If we try to use test method we will use it like this:
1. example
string x = "some string";
test(x);
or
2. example
test("some string");
could we make something to write variable inside parameter of method, something like
3. example (not valid)
test(new string("some string "));
point is that you put variable without previously define it like in 1 or 2 example
Sure, you can pass a "new" value into a function - you don't have to declare it outside of the function call.
I think your confusion comes from your incorrect syntax for creating a new StringBuilder:
test(new StringBuilder("New created string!!!")[0].ToString()));
or
test(new StringBuilder[]{new StringBuilder("New created string!!!")}[0].ToString()));
if your intent was to create an array of StringBuilders and then pass in the first one.
You can also use the output of another function directly in the call:
test(MethodThatReturnsAString());
Otherwise I have no idea what you're trying to do...
The cause of the confusion seems to be that System.String doesn't have a constructor that takes a System.String. The following statement will not compile:
string x = new string("some string");
However, this will:
string x = "some string";
For all intents and purposes, the above two lines are the same.
Why does this happen? Please observe the following code:
static class StringExtension
{
public static string Remove(this string s, char c)
{
return s.Replace(c.ToString(), "");
}
public static string Remove(this string s, char[] a)
{
foreach (char c in a)
{
s = s.Remove((char)c); // <---- ArgumentOutOfRange Exception here
}
return s;
}
}
class Program
{
static void Main(string[] args)
{
char[] a = new char[] { '.', ',' };
string testString = "Clean.this,string.from,periods.and,commas.";
Console.WriteLine(testString.Remove(a));
}
}
When I run this code, I get an ArgumentOutOfRange exception at the indicate line. Turns out that even if I have a specific code for an extension Remove (this, char) and I explicitly (although, there should be no reason for this) specify the parameter's type, it ignores my extension and tries to call the original Remove(int) method.
Am I doing something wrong or this is a bug in C#?
P.S. I use VS2010.
This line:
s.Remove((char) c);
is calling string.Remove(int) - the compiler will always use an applicable instance method instead of an extension method if it can. It's applicable due to the implicit conversion from char to int. That's the method that's throwing the exception, because the argument you're passing it is out of range. (In fact, you're lucky - in a worse situation it would be in range, and returning entirely unexpected results.)
In general I would strongly advise you not to create extension methods which have the same names as instance methods on the extended type, particularly if they've got the same number of parameters. Working out overloading is hard enough in general without adding extension methods to the mix. Don't forget that whenever you can't easily work out what your code is doing, someone reading the code in a year's time is going to have a ten times harder job.
I'm trying to figure out what I'm doing wrong here, but I can't seem to. I have this method that takes in a string and reverses it. However, when I print out the reversed string from the caller method, I just get "System.Char []" instead of the actual reversed string.
static string reverseString(string toReverse)
{
char[] reversedString = toReverse.ToCharArray();
Array.Reverse(reversedString);
return reversedString.ToString();
}
Calling ToString on a T array in .NET will always return "T[]". You want to use this instead: new string(reversedString).
By calling ToString you just get the default implementation that every class inherits from object. .NET can't provide a special implementation just for an array of char; the override would have to apply to all types of array.
Instead, you can pass the array to String's constructor, return new String(reversedString).
I am attempting to isolate (for localization purposes) the formatting of some messages. In one of the cases, I have several parameters, some of which may be an empty string. An example is probably called for here....
If the parameters are Parameter one and Parameter two then I want the result to be Some message Parameter one (Parameter two).
If the parameters are Parameter one and string.Empty then I want the result to be Some message Parameter one
If Parameter two was a numeric value, then I could use something like:
String.Format("Test {0}{1:' ('#')'}", "Parameter one", 12);
This operates as I'd expect - specifically if the second parameter is null the output is just Test Parameter one.
Unfortunately I haven't (yet) found a similar option which works with string parameters. Is there one?
Clarification: I am fully aware of numerous ways to get the result I need in code. I specifically want to know if there is a similar built-in mechanism for strings to the numeric one shown above.
You could always attempt writing your own custom string formatter by implementing IFormatProvider and ICustomFormatter
Then invoke it as
var stringValue = string.Format(new NewCustomStringFormatInfo(),
"Test {0}{1:' ('#')'}", "Parameter one", 12)
Depends on your situation, but you could do
string.Format(yourFormatString, paramOne, paramTwo).Replace("()", "");
No guarantees, as it is not fool-proof and makes the large assumption that your resulting string would only have "()" if paramTwo was empty.
You could create an extension method to help handle this and make it a little more concise.
public static string SomeWellNamedExtension(this string s)
{
if(string.IsNullOrEmpty(s))
return "";
return string.Format("({0})", s);
}
This method will handle the null/empty check and the parens. It's a pretty specialized method, so it's not likely to be useful almost anywhere else. But then your code would be like:
string.Format("Test {0}{1}, paramOne, paramTwo.SomeWellNamedExtension());
However, ymmv. This will affect your format string in that the parens are no longer its responsibility. I can't think of many super elegant ways of handling the use case you are talking detailing.
Unless you define a function that encloses a value in brackets, I can't see how you do it inline?
A simple example:
string.Format("Some message {0} {1}", "Parameter one", EncloseInParenthsisIfNotEmpty(""))
public string EncloseInParenthsisIfNotEmpty(string input)
{
if (string.IsNullOrEmpty(input)) return "";
return string.Format("({0})", input);
}
var s = System.String.IsNullOrEmpty(param2) ? string.Format(...) : string.Format(...)
You could write your own wrapper of String.Format (untested):
string MyFormat(string format, params object[] args)
{
object[] newArgs = new object[args.Length];
for(int i=0; i<args.Length; i++)
{
if(args[i] is string)
{
newArgs[i] = String.IsNullOrEmpty(args[i] as string) ? "" : string.Format("({0})", args[i]);
}
//numeric cases etc
else
{
newArgs[i]=args[i];
}
}
return string.Format(format, newArgs);
}
In c# , when sending a parameter to a method, when should we use "ref" and when "out" and when without any of them?
In general, you should avoid using ref and out, if possible.
That being said, use ref when the method might need to modify the value. Use out when the method always should assign something to the value.
The difference between ref and out, is that when using out, the compiler enforces the rule, that you need to assign something to the out paramter before returning. When using ref, you must assign a value to the variable before using it as a ref parameter.
Obviously, the above applies, when you are writing your own methods. If you need to call methods that was declared with the ref or out modifiers on their parameters, you should use the same modifier before your parameter, when calling the method.
Also remember, that C# passes reference types (classes) by reference (as in, the reference is passed by value). So if you provide some method with a reference type as a parameter, the method can modify the data of the object; even without ref or out. But it cannot modify the reference itself (as in, it cannot modify which object is being referenced).
They are used mainly to obtain multiple return values from a method call. Personally, I tend to not use them. If I want multiple return values from a method then I'll create a small class to hold them.
ref and out are used when you want something back from the method in that parameter. As I recall, they both actually compile down to the same IL, but C# puts in place some extra stuff so you have to be specific.
Here are some examples:
static void Main(string[] args)
{
string myString;
MyMethod0(myString);
Console.WriteLine(myString);
Console.ReadLine();
}
public static void MyMethod0(string param1)
{
param1 = "Hello";
}
The above won't compile because myString is never initialised. If myString is initialised to string.Empty then the output of the program will be a empty line because all MyMethod0 does is assign a new string to a local reference to param1.
static void Main(string[] args)
{
string myString;
MyMethod1(out myString);
Console.WriteLine(myString);
Console.ReadLine();
}
public static void MyMethod1(out string param1)
{
param1 = "Hello";
}
myString is not initialised in the Main method, yet, the program outputs "Hello". This is because the myString reference in the Main method is being updated from MyMethod1. MyMethod1 does not expect param1 to already contain anything, so it can be left uninitialised. However, the method should be assigning something.
static void Main(string[] args)
{
string myString;
MyMethod2(ref myString);
Console.WriteLine(myString);
Console.ReadLine();
}
public static void MyMethod2(ref string param1)
{
param1 = "Hello";
}
This, again, will not compile. This is because ref demands that myString in the Main method is initialised to something first. But, if the Main method is changed so that myString is initialised to string.Empty then the code will compile and the output will be Hello.
So, the difference is out can be used with an uninitialised object, ref must be passed an initialised object. And if you pass an object without either the reference to it cannot be replaced.
Just to be clear: If the object being passed is a reference type already then the method can update the object and the updates are reflected in the calling code, however the reference to the object cannot be changed. So if I write code like this:
static void Main(string[] args)
{
string myString = "Hello";
MyMethod0(myString);
Console.WriteLine(myString);
Console.ReadLine();
}
public static void MyMethod0(string param1)
{
param1 = "World";
}
The output from the program will be Hello, and not World because the method only changed its local copy of the reference, not the reference that was passed in.
I hope this makes sense. My general rule of thumb is simply not to use them. I feel it is a throw back to pre-OO days. (But, that's just my opinion)
(this is supplemental to the existing answers - a few extra considerations)
There is another scenario for using ref with C#, more commonly seen in things like XNA... Normally, when you pass a value-type (struct) around, it gets cloned. This uses stack-space and a few CPU cycles, and has the side-effect that any modifications to the struct in the invoked method are lost.
(aside: normally structs should be immutable, but mutable structs isn't uncommon in XNA)
To get around this, it is quite common to see ref in such programs.
But in most programs (i.e. where you are using classes as the default), you can normally just pass the reference "by value" (i.e. no ref/out).
Another very common use-case of out is the Try* pattern, for example:
string s = Console.ReadLine();
int i;
if(int.TryParse(s, out i)) {
Console.WriteLine("You entered a valid int: " + i);
}
Or similarly, TryGetValue on a dictionary.
This could use a tuple instead, but it is such a common pattern that it is reasonably understood, even by people who struggle with too much ref/out.
Very simple really. You use exactly the same keyword that the parameter was originally declared with in the method. If it was declared as out, you have to use out. If it was declared as ref, you have to use ref.
In addition to Colin's detailed answer, you could also use out parameters to return multiple values from one method call. See for example the method below which returns 3 values.
static void AssignSomeValues(out int first, out bool second, out string third)
{
first = 12 + 12;
second = false;
third = "Output parameters are okay";
}
You could use it like so
static void Main(string[] args) {
int i;
string s;
bool b;
AssignSomeValues(out i, out b, out s);
Console.WriteLine("Int value: {0}", i);
Console.WriteLine("Bool value: {0}", b);
Console.WriteLine("String value: {0}", s);
//wait for enter key to terminate program
Console.ReadLine(); }
Just make sure that you assign a valid value to each out parameter to avoid getting an error.
Try to avoid using ref. Out is okay, because you know what will happen, the old value will be gone and a new value will be in your variable even if the function failed. However, just by looking at the function you have no idea what will happen to a ref parameter. It may be the same, modified, or an entirely new object.
Whenever I see ref, I get nervous.
ref is to be avoided (I beleive there is an fx-cop rule for this also) however use ref when the object that is reference may itself changed. If you see the 'ref' keyword you know that the underlying object may no longer be referenced by the same variable after the method is called.