if - else initialize var [duplicate] - c#

Can I initialize var with null or some empty value?

C# is a strictly/strongly typed language. var was introduced for compile-time type-binding for anonymous types yet you can use var for primitive and custom types that are already known at design time. At runtime there's nothing like var, it is replaced by an actual type that is either a reference type or value type.
When you say,
var x = null;
the compiler cannot resolve this because there's no type bound to null. You can make it like this.
string y = null;
var x = y;
This will work because now x can know its type at compile time that is string in this case.

Well, as others have stated, ambiguity in type is the issue. So the answer is no, C# doesn't let that happen because it's a strongly typed language, and it deals only with compile time known types. The compiler could have been designed to infer it as of type object, but the designers chose to avoid the extra complexity (in C# null has no type).
One alternative is
var foo = new { }; //anonymous type
Again note that you're initializing to a compile time known type, and at the end its not null, but anonymous object. It's only a few lines shorter than new object(). You can only reassign the anonymous type to foo in this one case, which may or may not be desirable.
Initializing to null with type not being known is out of question.
Unless you're using dynamic.
dynamic foo = null;
//or
var foo = (dynamic)null; //overkill
Of course it is pretty useless, unless you want to reassign values to foo variable. You lose intellisense support as well in Visual Studio.
Lastly, as others have answered, you can have a specific type declared by casting;
var foo = (T)null;
So your options are:
//initializes to non-null; I like it; cant be reassigned a value of any type
var foo = new { };
//initializes to non-null; can be reassigned a value of any type
var foo = new object();
//initializes to null; dangerous and finds least use; can be reassigned a value of any type
dynamic foo = null;
var foo = (dynamic)null;
//initializes to null; more conventional; can be reassigned a value of any type
object foo = null;
//initializes to null; cannot be reassigned a value of any type
var foo = (T)null;

This is the way how to intialize value to var variable
var _myVal = (dynamic)null;

Why wouldn't this be possible?
var theNameOfTheVar = (TheType)null;
eg:
var name = (string)null;
Simple as that.

A var cannot be set to null since it needs to be statically typed.
var foo = null;
// compiler goes: "Huh, what's that type of foo?"
However, you can use this construct to work around the issue:
var foo = (string)null;
// compiler goes: "Ah, it's a string. Nice."
I don't know for sure, but from what I heard you can also use dynamic instead of var. This does not require static typing.
dynamic foo = null;
foo = "hi";
Also, since it was not clear to me from the question if you meant the varkeyword or variables in general: Only references (to classes) and nullable types can be set to null. For instance, you can do this:
string s = null; // reference
SomeClass c = null; // reference
int? i = null; // nullable
But you cannot do this:
int i = null; // integers cannot contain null

Nope. var needs to be initialized to a type, it can't be null.

Well, I think you can assign it to a new object. Something like:
var v = new object();

var just tells the compiler to infer the type you wanted at compile time...it cannot infer from null (though there are cases it could).
So, no you are not allowed to do this.
When you say "some empty value"...if you mean:
var s = string.Empty;
//
var s = "";
Then yes, you may do that, but not null.

you cannot assign null to a var type.
If you assign null the compiler cannot find the variable you wanted in var place.
throws error: Cannot assign <null> to an implicitly-typed local variable
you can try this:
var dummy =(string)null;
Here compiler can find the type you want so no problem
You can assign some empty values.
var dummy = string.Empty;
or
var dummy = 0;

you can't initialise var with null, var needs to be initialised as a type otherwise it cannot be inferred, if you think you need to do this maybe you can post the code it is probable that there is another way to do what you are attempting.

Thank you Mr.Snake, Found this helpfull for another trick i was looking for :) (Not enough rep to comment)
Shorthand assignment of nullable types.
Like this:
var someDate = !Convert.IsDBNull(dataRow["SomeDate"])
? Convert.ToDateTime(dataRow["SomeDate"])
: (DateTime?) null;

How about default keyword?
var foo = default(SomeClass);
Compiler doesn't lose what type the foo has. foo will have default value of reference type, null

Related

When should I use var and when should I use string, ulong, int, etc [duplicate]

This question already has answers here:
Using var or not using var [duplicate]
(3 answers)
Closed 4 years ago.
What is the "proper" way to use
var x = "text";
or
string x = "text";
Does it matter which I use? Is there a "standard" way people usually do it? I only ask because sometimes Rider suggests that I use var.
There are a few times where you must use an explicit type, and instances where you must use var.
Must use explicit type:
If you declare a variable without initializing it, or, if you want to initialize a variable explicitly as null
string myString;
int i;
string someString=null;
DateTime? nullableDate=null;
Must use var:
When you use an anonymous type, or a generic type with one or more type parameters that are anonymous types.
var stuff = new {Name="Bob", Age=25};
var bunchOfStuff = from item in items select new {item.Name, item.Age};
Otherwise
It's a question of style and/or taste
var is mostly syntactic sugar however there are times when you must use var and that's when you assign variables to anonymous types.
Anonymous type example:
var anonymousType = new { Name = "Mathew", DOB = DateTime.Now };
Console.WriteLine($"{anonymousType.Name} : {anonymousType.DOB}");
As far as when to use it otherwise... this is an opinion and or team guideline. There's nothing gained or lost doing it either way.
That said; here's my opinion.. this question will get put on hold for too broad but in the mean time here's a little something to look at however you choose.
I like var but I believe it can be confusing if you're not careful how you name / use variables but... personally I prefer var. It's shorter and can clean up code or make it somewhat shorter. Especially when you have somethin like Person person = new Person(); There's just too many Person's there for me... I also like how var mimics the syntax of JavaScript somewhat (although the two declarations are different).
var is not different than declaring the type out right so in your question string x or var x it doesn't matter. The compiler infers the type that is being assigned and that's what var becomes.
I do recommend this... When you declare ANY variables, especially those using var I would always name the declaration as close to the type as possible so that it doesn't matter which you choose. Name the variables correctly and no one should give you a hard time either way... Then again; this is all opinion.
var person1 = new Person();
Person person2 = new Person();
var employee1 = new Employee();
Employee employee2 = new Employee();
var employee3 = new Employee();
Person person3 = new Employee();
person1.Name = "Mathew";
person2.Name = "Mark";
employee1.Name = "Luke";
employee2.Name = "John";
employee3.Name = "Acts";
person3.Name = "Romans";
The documentation for var says:
An implicitly typed local variable is strongly typed just as if you had declared the type yourself, but the compiler determines the type.
In the end, there is functionally no difference. So, to answer your question, no, it doesn't matter which one you use. And it is for that very reason that there is no "standard" or "proper" one to use.
Use what you prefer.

How to use variable type in as operator

For example:I have 2 variable (value ) & (property) i want to check is cast possible for value? We do not know the type of variables, How to check if cast is possible?
var value = Reader[item];
PropertyInfo property = properties.Where(x => x.Name == item).FirstOrDefault();
var type=property.PropertyType;//Or property.ReflectedType
var cs= value as type // Error: type is variable but is used like a Type
if (cs!=null){
...
}
Sample 1:
var value = 123;//is int
type = property.GetType();// is double
var x = (double)value;//Can be casted
Sample 2:
var value = "asd";//is string
type = property.GetType();// is double
var x = (double)value;//Can not be casted
You can use IsAssignable:
bool isValidCast = type.IsAssignableFrom(value.GetType())
As per the comments about int to double:
I've made a mistake in my comment, so i deleted it.
int can be implicitly converted to double because there is a predefined implicit conversion, see here
There are many ways to convert or cast from type to type. For example, You can use implicit/explicit conversion, you can use TypeConverter or implement the IConvertible interface.
Now, you have to decide which use case is relevant to you. It can be a bit complex to check them all, especially without knowing the destination type at design time.
In your code snippet, type is a variable of type Type, hence why it is throwing that error. You can change your code to use Convert.ChangeType() instead. Something like this:
var value = Reader[item];
PropertyInfo property = properties.Where(x => x.Name == item).FirstOrDefault();
var type=property.PropertyType;
object cs= Convert.ChangeType(value, type);
if (cs!=null){
...
}
Notice that, since you don't know the strong type of your property at compile time, you still have to box it into an object type after changing its type. This means you wouldn't be able to access its properties and methods directly using dot syntax in code (e.g. cs.MyProperty). If you wish to be able to do that, you can use the dynamic type in C#:
dynamic dcs = cs;
Console.Write(dcs.MyProperty);
When using Convert.ChangeType() you have to make sure you are converting to the correct type. E.g.:
if (value.GetType() == type)
{
object cs= Convert.ChangeType(value, type);
}

Dapper: What's the difference between these two pieces of code?

I've registered a custom type handler for Dapper to Json serialize a string. This works as expected. However, whilst coding, I discovered two pieces of code after refactoring, the latter one which didn't trigger the datatype handler, but should in my opinion, so what's the difference?
First the code that works as expected - the custom type handler is called by dapper, and the data is serialized when inserted into the table:
if (val.GetType() != typeof (String))
{
var v = new JsonString {Value = val};
this.Connection.Execute("insert into misc (k,v) values (#keyName, #v)",
new { keyName, v });
}
else
{
this.Connection.Execute("insert into misc (k,v) values (#keyName, #val)",
new { keyName, val });
}
Now for the code which doesn't work as it inserts into the table the fully qualified type string instead of the serialized data, but which I think is semantically similar:
var v = val.GetType() != typeof (String)
? new JsonString {Value = val}
: val;
// t is set to type of JsonString, therefore the dapper type handler should be used
var t = v.GetType();
this.Connection.Execute("insert into misc (k,v) values (#keyName, #v)",
new { keyName, v });
Is it a dapper bug or a c# oddity? I assume it's something to do with the auto typing in the ternary conditional which is the failing point, but t is set to the data type that is serialized by Dapper (or rather the custom type handler). What's the difference?
I am going to assume that the compile-time type (i.e. declaration type) of val is System.Object. I will explain why the two situations are not equivalent.
One must be careful to distinguish between the compile-time type of a variable and the actual run-time type (which is found by .GetType()).
In the first piece of code, in the branch where val is not String at run-time, we declare:
var v = new JsonString {Value = val};
Here var is substituted by JsonString since that is the compile-time type of the right-hand side of the = assignment. Then the anonymous type instance:
new { keyName, v }
is going to be a class (I will call it class Anonymous1) with a member
public JsonString v { get { ... } }
Now, in the second piece of code, we have instead:
var v = val.GetType() != typeof (String)
? new JsonString {Value = val}
: val;
The compile-time types of the operands to the ternary operator are:
{bool} ? {JsonString} : {object}
At compile-time, a best common type for JsonString and object must be found. That common type is object. So object becomes the compile-time type of v here, i.e. var means object here.
Then the anonymous type:
new { keyName, v }
is a type "Anonumous2" whose "2nd" property reads:
public object v { get { ... } }
So to sum up: In the first case you pass in an object which has a property v declared as a JsonString which when retrieved returns a JsonSting that happens to have run-time JsonString. In the second code sample you pass in an object which has a property v declared as object which when retrieved returns an object that happens to have run-time type JsonString.
I do not know much on how Dapper works! But presumably when it sees (by reflection?) that the property type is object, it simply calls .ToString() on it. If that object happens to be of run-time type string, that should be OK, since string.ToString() is overridden. But JsonString.ToString() is not like that.
When Dapper sees the property is declared as JsonString, Dapper does something smarter than calling .ToString().
Assuming there is no implicit conversion available between JsonString and String, the code in the second example won't work. If there is an implicit conversion available, you need to provide more information about the exception that is occurring.
WIth no conversion available between JsonString, a variable declared with type var has a type that is inferred by the compiler ((https://msdn.microsoft.com/en-us/library/bb384061.aspx). In this case, variable v is either of type JsonString or String depending upon which part of the assignment occurs. If the compiler assumes it is of type JsonString, any assignment with a String will fail.
In your second code example, the first line of code is wrong since the assignment results in two different data types getting assign to variable v.

Creating List with non-knowing type

Why in C# I can not write
MyClass m = new MyClass(2,3);
Type T = m.GetType();
List<T> ll = new List<T>();
or something like
MyClass m = new MyClass(2,3);
Type T = typeof(m);
List<T> ll = new List<T>();
??
Is it possible to change this code and write anything similar??
Although generics are resolved at run time, the compiler provides safety checks. It thus requires you to specify the class name and not an instance of Type when typing statements like List<MyClass>...=
ie specify the type instead of passing a Type instance.
If you wish to have a generic that is resolved at execution time you would have to use reflection.
See
http://msdn.microsoft.com/en-us/library/system.type.makegenerictype%28v=vs.110%29.aspx
You could try something like this:
Type x = typeof(Foo);
Type listType = typeof(List<>).MakeGenericType(x);
object list = Activator.CreateInstance(listType);
You could cast the Activator's result as IList to have access to its methods.
var list = (IList)Activator.CreateInstance(listType);
Of course you shouldn't expect any type safety here as the resulting list is of type object at compile time. Using List would be more practical but still limited type safety because the type of Foo is known only at runtime.
You could also read more about it here

Idiomatic way to test for Generic Type in C#

If I can test for basic class types like this in C#:
bool stringTest = new string() is string;
// and
bool listOfStringTest = new List<string>() is List<string>;
How do I test for List of anything or List
I know I could use reflection to figure it out, but is there a easier and more idiomatic way to do it in C#?
For example, if I tested List<int> or List<string> both would return true. And Nullable<int> and DateTime would return false. Note: just using List<> as the example looking for something general purpose.
I think the only way to do this is using reflection:
Type listType = new List<string>().GetType();
bool isList = listType.IsGenericType && list.GetGenericTypeDefinition() == typeof(List<>);
For an exact match, you can use the Type.GetGenericTypeDefinition method:
bool listOfStringTest = new List<string>().GetType().GetGenericTypeDefinition() == typeof(List<>);
As suggested by Lee, you have to make sure the type in question is generic to use this method.
I'm not entirely sure what you're after. If you want to find out if an object is usable as a specific type, then I try to use Type.IsAssignableFrom where ever I can. If you're looking to see if an instance is a constructed generic type of an unbound generic type (e.g. constructed generic List<string> is a type of unbound generic List<>, which seems to be the only case you couldn't do with is in your description) then you can do something like this:
var type = obj.GetType();
bool b = type.IsGenericType && typeof (List<>).IsAssignableFrom(type.GetGenericTypeDefinition());
That tells you, in a hypothetical world where you could declare a variable of type List<>, that that variable could be assigned the value of obj.
Unfortunately you need the IsGenericType check first because some GetGenericTypeDefintion implementations thrown an exception if the type is not generic (had they returned null, IsGenericType would not be needed).

Categories

Resources