I noticed that in C# that the + operator takes a string on the left and an object on the right:
string output = "" + numbers.ElementAt(0);
//vs
string output = numbers.ElementAt(0).ToString();
Why is the default behavior to accept an object on the right and not a string? When I look other + operators for say int, it is strongly typed for int/int instead of int/object.
I know in C# all objects have the ToString() method, is this just a way to remove the need to call .ToString() in the first example above?
Why is the default behavior to accept an object on the right and not a string?
Well, first off, there is an overload that accepts two strings, and if you pass two strings that's the overload that will be used, so it is the default behavior. But if you pass a string and a non-string, then the (string, object) overload will be used.
As for why that overload is there, it's because the C# language designers felt that it was entirely sensible to concat a string to any object, and had a reasonable implementation for doing so for any type of object.
When I look other + operators for say int, it is strongly typed for int/int instead of int/object.
How would you implement a operator +(int, object) overload? I don't see any good implementation here, unlike with string concatenation.
I know in C# all objects have the ToString() method, is this just a way to remove the need to call .ToString() in the first example above?
It actually works if the object is null, whereas your solution does not. If you would account for that then yes, that is essentially all that the overload is doing.
is this just a way to remove the need to call .ToString() in the first example above
Yes.
String concatenation automatically transforms non-strings into strings.
Source: C# Language Specification: Addition operator, MSDN.
Related
Im starting the second course in computer programming and right now I have an intermediate level of C language knowledge, beginner C++ and just have started learning C# language. In C# fundamentals by Bob Tabor he uses the . as class operator eg.
Console.WriteLine(myValue); Console.ReadLine();
Where Console is the class and WriteLine is part of this class. To keep everything organised I was trying understand all the concepts of it but in one moment he converted an integer to string by using function:
myValue.ToString();
And in that point I got lost. Why he uses that logic instead of simple and organised way like:
System.ToString(MyValue);
He hasn't used the value that has to be converted as an argument. That just doesn't make any logic sense.. Am I wrong?
Every object inherits from System.Object (except object itself) in the .NET Framework. And System.Object defines a public ToString() method, therefore you can call ToString() on any object.
Console.WriteLn calls ToString on objects passed to it as argument, in order to get a string it can print.
There is no such thing as System.ToString(). System is a namespace and a method cannot exist in the global scope; it is always a member of a type. From within an object you can call the members directly, from outside you must use the dot syntax: someObject.SomeMethod(); or x = someObject.SomeProperty;. Static members are called from the type name: SomeType.SomeMethod();. Console.WriteLn(); is a good example.
The only functional difference is that Convert.ToString() handles null, while ToString() doesn't, since obj.ToString() presumes the obj is not null, whereas ToString(obj) will return String.Empty on a null object.
Every object has methods and properties, you call the method "ToString" to format the object as an string.
If you realize you are writting less than calling a system method to formart it.
Both of these are accepted by the compiler:
ssMinnow = listStrLineElements[VESSEL_TO_AVOID].ToString();
ssMinnow = listStrLineElements[VESSEL_TO_AVOID];
Is one way preferable to the other? ToString() or not ToString(), that is the question.
It is not only redundant, but also is dangerous: if listStrLineElements[VESSEL_TO_AVOID] happens to be null, your application is going to throw an exception if you use ToString(); without ToString(), it would simply assign null to ssMinnow.
If listStrLineElements[VESSEL_TO_AVOID] returns a string, then yes, it is redundant. if it returns some other type, then no, it is not redundant.
in General your don't need to invoke the ToString() method is the object type returned is already a String.
in your example we cannot tell that as ssMinnow does not show the declaration type :I assume you have used var keyword which will work with both of them or listStrLineElements[VESSEL_TO_AVOID] returns already a String
Simply redundant. I prefer to leave off ToString() where its not needed but its a judgement call.
Don't use ToString if you are already returning a string. You're just adding unnecessary overhead.
It is not so simple as stated. Redundant, possibly; good or bad, a matter of opinion. Since toString() will be called anyway if the object is treated as a string somewhere, the explicit use of toString() can serve as a signpost to the developer reading the code. The explicit call describes more of the original intent than leaving it as an assumption for the compiler to fulfill.
As far as I know, there are at least 3 ways to convert data types in .NET:
using System.ComponentModel.TypeConverter
var conv = System.ComponentModel.TypeDescriptor.GetConverter(typeof(int));
var i1 = (int)conv.ConvertFrom("123");
using System.Convert.ChangeType():
var i2 = (int) Convert.ChangeType("123", typeof (int));
using the Parse/TryParse methods of the destination type:
var i3 = int.Parse("123"); // or TryParse
Are there any guidelines or rules-of-thumb when to use which method to convert between the .NET base data types (especially from string to some other data type)?
I'm going to post here 6 years late, because I think this is a good question and I am not satisfied with the existing answers.
The static Parse/TryParse methods can be used only when you want to convert from string to the type that has those methods. (use TryParse when you expect that the conversion may fail).
The point of System.Convert is, as its documentation says, to convert from a base data type to another base data type. Note that with Convert you also have methods that take an Object and figure out by themselves how to convert it.
As to System.ComponentModel.TypeConverter, as the "typeconverter" stack overflow tag's documentation, they are used primarily to convert to and from string, when you want to provide a text representation of a class instance for use by designer serialization or for display in property grids
Convert
Convert class uses the IConvertible methods implemented in the target type.
Unfortunately, implementing IConvertible means writing lots of boilerplate code and Convert.ChangeType causes boxing if the target type is a struct.
TypeConverterAttribute
TypeDescriptor.GetConverter uses the TypeConverterAttribute and IMHO offers both a better API to convert a type and a more elegant way to make a type convertible. But it suffers the same performance issues with the Convert class, caused by the methods not being generic.
Parse/TryParse
Using T.Parse/T.TryParse methods is the de facto way of creating an object from a string since it doesn't involve unnecessary boxing. They also usually have overloads that provide greater control of how to parse the string.
TryParse methods allow you to handle cases where the string you want to parse is obtained from user input or another mean that doesn't guarantee a properly formatted string, without throwing exceptions.
So you should call the type's Parse/TryParse methods when you can and fallback to the other ways only when you don't know the target type in the compile time, i.e. when you only have a Type object that represents your target type.
You can also have look at my little library called ValueString that finds the most suitable parsing method of a type and uses it to parse the string.
According to my personal preference and coding standards I choose between the following:
Convert. I use this when I am absolutely sure that the values will be what I expect.
int i = Convert.ToInt32("123");
TryParse. I use this when I am handling user input. This also has the benefit to be able to use localized formatting when parsing.
int i = 0;
bool parsed = Int32.TryParse("123", out i);
There is also the possibility to use TryParseExact, where a certain pattern can be parsed. It can be useful in certain cases.
Just found out a case that TypeConvert.ConvertFrom(object) throws exception.
If you want to convert an Integer 0/1 to a Boolean. You will get exception using TypeConvert.ConvertFrom(1) or (0). In this case, Convert.ChangeType(1, System.Boolean) works.
As a general rule of thumb, you should be avoiding the Convert class altogether. There are reasons to use it (e.g, you do not know the source type), but if you already know your source type is a string then Parse (or, more correctly, TryParse) is always the right method to use.
As for type converters, they are more often than not used when a framework (such as WPF) uses reflection to determine the right sort of type converter.
You forgot another way of converting, that is the direct cast. Take this code for example
object i = 1;
int myInt = (int)i;
This is a bit of a contrived example, but I already know that i is an int, its just that its boxed into an object. In this case I do not need to convert i, I just need to directly cast it to the type which I know it already is.
I pretty much always use the int/double/etc.Parse() methods, when I'm certain it's a number. In any case of doubt, I us the .TryParse() methods, as an all-in-one solution including parsing and checking. I have this feeling that checking and parsing combined is slightly more performant than doing them separately.
TypeConverter is probably only useful when you don't really know the types at compile time.
Another late answer. I have an application where I was using some code that looks like this:
var finalValue = Convert.ChangeType(sourceValue, targetProperty.PropertyType);
sourceValue would be a string representation of what I wanted which normally would be a primitive under a wrapper class. This way would work with regular data types. Even with entire classes. However, one day I stupidly decided to change the datatype of a property that was a double to a nullable one double? guess what? boom!
invalid cast from string to nullable double
This is the perfect scenario where you should use the TypeConverter class as follows:
void Main()
{
var ss = new[] {"2.01", "3.99", ""};
var conv = TypeDescriptor.GetConverter(typeof(A).GetProperties().First().PropertyType);
Console.WriteLine(string.Join(",", ss.Select(s => conv.ConvertFrom(s))));
}
class A {
public double? b {get; set;}
}
//2.01,3.99,
I have some code like:
int value = 5;
MessageBox.Show ( value );
and the MessageBox.Show complains saying:
"cannot convert from 'int' to
'string'"
I seem to remember some cases where values seem to be implicitly converted to string values, but can't recall them exactly.
What's the reason behind this decision that any value isn't implicitly convertible to string values?
MessageBox.Show() only accepts a string. When you use something like Debug.WriteLine, it accepts a bunch of different object types, including object, and then calls ToString() on that object. This is probably what you're experiencing.
A short solution (everywhere you need a string):
MessageBox.Show(""+value);
But I would prefer a ToString() or a String.Format() in most cases.
To answer the "Why" part: because implicit conversions can be dangerous and can undermine type-safety.
"1" + 2 = "12" = 12, not always what you want or expect.
For the exact reason, you would have to ask either the C# compiler guys, or one of the .NET runtime guys.
However, there are no places in the .NET framework or the C# language where values are automatically and implicitly convertible to strings.
You might, however, think of the way string concatenation works, but that only works because there are a lot of overloads on the string.Concat method, including one that takes an object.
In other words, this is allowed:
string s = "Hello there: " + 4;
Other methods around in the framework also has lots of overloads, such as Debug.WriteLine and such, where it will easily accept your integer or decimal, convert it to a string through a call to .ToString, and then print it.
It isn't, however, something built into string or int, but the method itself.
Try
MessageBox.Show(value.ToString());
This is super dumb, but I've googled and checked references and I just cannot find an answer... Why can an int or float etc be added as part of a string without converstion but not on it's own? that is:
while this work fine:
string st = "" + 12;
this doesn't (of course):
string st = 12;
Where is the magic here? I know it works I just want to know WHY it works and how I control HOW the conversion is done?
In the first statement, the left operand for the + is a string, and as such + becomes the concatenation operator. The compiler finds the overload for that operator which takes a string and an arbitrary value as operands. This converts both operands to strings (using ToString()) then joins them.
The second statement does not work because there's no implicit cast from int to string.
You can control how the conversion is done by using parentheses to change the order of operations (semi-effective) or by writing code to handle the conversions pre-emptively.
This is how string concatenation is designed to work, and as BoltClock's answer noted, the compiler is using the + as the string concatenation operator. From the C# Language Specification on string concatenation, we find that:
Any non-string argument is converted to its string representation by invoking the virtual ToString method inherited from type object.
String concats in .NET ultimately resolve to calls to one of the overloads of the static String.Concat methods. This is an optimization to reduce the number of temporary strings that would otherwise be created when mutliple concatenations occur in a single statement.
In short the reason this works is because a number of the String.Concat overloads will accept object in the argument list and since an int, float etc. are in essence objects they can be passed to the Concat overload that accepts one or more object parameters. Internally Concat of basically does a .ToString() on the incomming object therefore turning your int into it's string representation.
In your specific example
string st = "" + 12;
The compiler will reconize that the first string is empty and simply call the String.Concat(object) overload. Which will convert the integer 12 to a string and assign it to st.
This overload is called because the integer can be implicitly boxed to fit into the object type and therefore satisfy the method overload selection.
Because the compiler will call .ToString() on all objects if one of the parameters is a string.
This is working because of the operator overload of the operator + on the string datatype.
Because the first is an expression and there C# makes an implicit conversion.
The second is an assignement with a static value, and the static value has no methods to be called.
As long as the value to be asigned is a variable or expression return there will be a toSting method to call.
It's because the compiler translates the addition to a call to String.Concat().
Internally, all operands are boxed (if necessary) and passed to the String.Concat method (which of course calls ToString() on all arguments).