In C#, when calling some instance methods, We always declare a variable of that type, then assign a value to it, and call that method at last:
string str = "this is a string";
int test = str.IndexOf("a");
In Javascript, we can do this:
var test = 'sdfsldkfjskdf'.indexOf('a');
Is this kind of method calls legal in C#, say, directly use the string literal as a shorthand, without the declaration of a variable?
Yes, it's absolutely valid and fine.
I suspect you don't always declare a variable even without using literals. For example, consider:
string x = "hello";
string y = x.Substring(2, 3).Trim();
Here we're using the result of Substring as the instance on which to call Trim. No separate variable is used.
But this could equally have been written:
string y = "hello".Substring(2, 3).Trim();
The same is true for primitive literals too:
string x = 12.ToString("0000");
Ultimately, a literal is just another kind of expression, which can be used as the target of calls to instance methods.
Yes it is possible. However I would not recommend it in general, because it is confusing, and not clear to other developers what you are doing.
Yes it's valid. No problem with it.
Yes, and the best thing about it is that you don't even have to check for null.
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.
I was looking at the following question, comparing casting to converting, which basically stated (Through all the answers), that if you know your object is a string, use (string) rather than .ToString().
That got me thinking - what if your object might be a string or int? Or does knowing its a string also extend to integers?
Would this rule apply to a byte too? (Accidently used bit earlier)
Edit
This answer shows many ways of converting an integer to a string, but that still doesn't explain which to really use.
Specifically, casting a number to a string presents no real issue, as any number can be expressed as a string (Important: not every string, however, can be expressed as an number! e.g. how would you express "banana" as a number?)
string mystring = mynumber.ToString();
works everytime, without fail (assuming non-null values in case you're using nullable types).
The same exact method applies for any primitive type, and some others (DateTime, StringBuilder, ...)
It's the conversion from string to number that can be problematic. Usually not the other way around.
Edit if you want to take advantage of direct (string) casting in case your starting object is already a string, maybe this can help?
string mystring = (myobject as string) ?? myobject.ToString();
myobject as string will try to directly cast the object to a string. If it fails, that returns null.
?? myobject.ToString() then makes sure that, in case the previous attempts resulted in null, the regular .ToString() method is called as a fallback scenario.
If you have an object which is of type int but is boxed as an object, you cast it back:
object myBoxedStr = "stringvalue";
string unboxedStr = (string)myBoxedStr;
http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx
If you have a string which contains an int value, you parse (or tryparse) it
string myIntStr = "5";
int myInt = int.Parse(myIntStr);
If you don't know if the boxed type is the assummed type you use is and as
object assumedMyType = new MyType();
MyType myType = assumedMyType as MyType;
the as keyword returns null if the conversion has failed (rather than throwing an exception)
With the is keyword you can check if the assumed type is of the correct type before converting it
object assumedInt = 5;
if(assumedInt is int)
{
int myInt = (int)assumedInt;
}
The takeaway from that question is that if you know that your value is actually of the type you want, then you should cast it (e.g. (int)). This has several benefits: it is efficient, it clearly expresses your intent, and it will fail conspicuously if your presumption is false.
You use other sorts of conversions when you don't know that the value of the type you want, or when you know that it is not. For instance, if you have an array of strings, you should not use (int), but rather ParseInt and its ilk. If you have an array of objects, some of which are ints, then the as operator might be what you want.
string name = GetSql["username"].ToString();
This code running slow. Because object(object, int, double etc.) to string converting operations.
string name = (string)GetSql["username"];
This code very fast running. Because not converting operations only type designation.
int to string convert.
1-)
var number = 0;
int.TryParse("213", out number);
It is better to TryParse method because it can block error occurs.
2-)
var number = int.Parse("123");
I think that the best option, if you strongly suspect that it's a string, but not actually sure, is something like this:
string valueString = value is string ? (string) value : (value ?? string.Empty).ToString();
My experience is that best cast/convert is archived through Convert class. That's the way C# expecting from you. That class care about all that ugly things that would you normally do.
When you do type conversion or simply typecasting, it even round float to int.
Can someone explain to me the difference between these two string variables :
dynamic dateStrAsDynamic = "12/10/2013";
var dateStrFromDynamic = dateStrAsDynamic.ToString();
var regularDateStr = "12/10/2013";
These two behave exactly the same way but while debugging calling DateTime.Parse on the first one tells me that this dynamic operation is not supported while debugging, I mean "which dynamic operation?", whatever dynamic operation it is; must it not have been over?
The IL code generated by calling DateTime.Parse on those two (of course after ToString is called and assigned to dateStrFromDynamic) have a large difference as well that I am not able to grasp totally.
Do these two really have a difference, or am I missing something?
I mean "which dynamic operation?"
The one that invokes a method using a dynamic variable as the argument.
Note that the type dateStrFromDynamic will still be dynamic - the compiler doesn't know that ToString() will definitely return a string. The result of almost any dynamic operation is another dynamic value - if you want to tell the compiler that you want the type of dateStrFromDynamic to be string, you need to make that explicit:
string dateStrFromDynamic = dateStrAsDynamic.ToString();
Or just:
string dateStrFromDynamic = dateStrAsDynamic;
(given that it really is a string to start with).
So yes, there is an enormous difference between dateStrFromDynamic and regularDateStr - and if you hover over var in Visual Studio, it will become more obvious as it will tell you the type that the compiler has inferred for each variable.
Just started learning C# (in xaml), so appreciate some elaboration:
((MSAvalon.Windows.Serialization.ILoaded)(_Text_2_)).DeferLoad();
Not sure what all the round brackets means... does it mean "_Text_2_" is a child of object "MSAvalon.Windows.Serialization.ILoaded" ?
and if so... why not just something like:
MSAvalon.Windows.Serialization.ILoaded._Text_2.DeferLoad();
_Text_2_ is casted to a MSAvalon.Windows.Serialization.ILoaded Object/Interface and then the method DeferLoad is called
This is a typecast, used to tell the compiler that a variable is of a particular type when it's not obvious. It could have been used like this:
class Foo {
private object _Text_2_;
void Method() {
((MSAvalon.Windows.Serialization.ILoaded)_Text_2_).DeferLoad();
}
}
Leaving out the typecast here would cause a compiler error, since DeferLoad is not a method of object. You're telling the compiler here that you have some special knowledge that _Text_2_ is really what you say it is.
Basically it's started with (( so that DeferLoad can be called. I'll illustrate with an example.
Lets say you do the following.
object s = "Hello world";
s now contains a string. If you want to make this string uppercase using a cast (as in your example, I can't simply write this
(string)s.ToUpper();
ToUpper() can't be called, since it's not valid on a variable of type object. If you rewrite this to
((string)s).ToUpper()
it's valid. Because of the brackets, s is casted to a string first, then string.ToUpper() is called on the variable.
Note that in this case (s as string).ToUpper() would be a cleaner approach.
So for complex types, we can write:
return new MyType ( 5 );
but why can't we do stuff like (to have symmetry for one):
return new int ( 5 );
return new Int64 ( 5 );
I know only parameterless constructors are provided. What's the reason for this?
What would be the point? Any of the .NET value types that don't have a constructor have a literal form. If they didn't have a literal form, it would be impossible to provide a constructor that takes its type as a parameter.
Since you have the literal, providing a constructor which takes that literal makes no sense.
Without literal, impossible
int i = new int(new int(new int(...)));
With literal
int i = new int(5); // What is the point? Would the constructor do *anything*
// besides int i = 5?
Part of design is knowing what to leave out. Since it doesn't add value, it wasn't coded.
It's just that these types only have a default constructor. A lot of other complex .net type only have a default constructor as well. I would guess the reason that there isn't a parameterized one is because, as mentioned by other answers, there isn't really a good reason for one.
This may sound odd but why would you want to? - complex types make sense since you are using 1-n inputs to get a result but the int just returns an int...so why?