Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Apologies in advance if the question is opinion based. Why would you pick the first variant of the following three, while declaring local variables in C#?
var list1 = new List();
List list2 = null;
var list1 = new List();
var list2 = (List)null;
// this variant would allow easy refactoring from class to struct
var list1 = new List();
var list2 = default(List);
While this is impossible:
var list1 = new List(), list2 = null;
EDITED to provide the context:
void DoSomething(Action action) { /* ... */ }
// ..
var list1 = new List();
List list2 = null;
// ...
DoSomething(() => { list2 = new List(); list2.Add(1); });
var is shorter and some people prefer it over specifying the type explicitly. In the context of anonymous types, you don't have an option except to use var, such as in
var point = new { X = 1, Y = 2 }
var is only syntactic sugar though. Not specifying the type does not mean it's dynamic. It only means the compiler will infer the type from usage. In the end, the compiled code is the same.
Within our team, we have a standard to use var on the left side when the right side is one of the following:
New object construction
Cast
Anonymous
In all other cases our internal standard does not allow var because in other cases it may not be explicitly clear what the variable type is to the reader (even though the compiler knows). For example, if you have a statement like this:
var x = SomeMethod();
What is the type of x? The compiler knows because it knows what SomeMethod() returns. Do you remember off-hand? Do you remember for every method in your application? We find it more expressive to not use var in these cases.
For a null value, I would always specify the type. Casts and such seem like just an odd mechanism to allow you to use var when it really gains you nothing.
List list = null;
In case 2, all that you're doing is telling the compiler that list is going to be a List type object, and it will be initialized to null. You could do that, but it's a roundabout way of declaring a variable as being of type List.
You would only want to use case 3 if you're dealing with generics. The point of it being that you may not know if the type is a reference type or a value type, var list = null is not a valid statement for value types. The default keyword will ensure that either null is set for reference types and 0 for value types.
Answer:
According to MSDN Reference: Implicitly Typed Local Variables
var can only be used when a local variable is declared and initialized in the same statement; the variable cannot be initialized to null, or to a method group or an anonymous function.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have tried to create a generic list with different datatypes.
For example, I have an string array:
string[] stringArray = new string[] {"integer", "double"};
and I want to create a list with the given types in the string.
For example:
List<stringArray[0]> intList = new List<stringArray[0]>();
but this does not work.
Does anyone know how to do this without if statements?
Edit:
I just would like to create different lists with different types with a loop. In my example there then would be 2 lists (int and double). If there would be another element e.g called bool. There would be three lists (an int list, a double list and a bool lost)
List<Type> would be a better option. The example below creates a collection of Type then iterates over the collection creating a new instance of each item.
// Generic List
var types = new List<Type>();
// Add Types
types.Add(typeof(int));
types.Add(typeof(double));
// Iterate List
foreach(var type in types)
{
// Dynamically create instances of type
var instance = Activator.CreateInstance(type);
// Insert additional code
}
Something like this will work:
string[] stringArray = new string[] { "System.Int32", "System.Double" };
List<object> intList = new List<object>();
foreach (string tipo in stringArray)
{
try
{
intList.Add(Activator.CreateInstance(Type.GetType(tipo)));
}
catch (TypeLoadException e)
{
Console.WriteLine("{0}: Unable to load type", e.GetType().Name);
}
}
But keep in mind the strings must be fulll qualified Types (like "System.Int32")
If you only need a list of the Types, omit the Activator.CreateInstance()
This question already has answers here:
How to modify a foreach iteration variable from within foreach loop?
(4 answers)
Is there any way to do this, assign a value within a List<T>.ForEach() statement?
(4 answers)
Closed 7 years ago.
It seems weird to me. Thought if someone can clear my doubt please.
var list = new List<SomeClass>();
Now if we use ForEach extension method of collection
list.ForEach(c=>c.SomeProperty = SomeValue);
So now we can get the updated value. So it seems to be reference type. And Yes ForEach takes an Action so its reference type. But if try to re-initilize the object inside the ForEach I do not see expected behavior.
list.ForEach(c=>{
if(SomeCondition) // lets consider its always true now.
{
c = new SomeClass();
}
});
So after this execution I was expecting fresh list. And should not contain the reference of old object. But if I print the list. I can see the old values.
So why ForEach didnt re-initialize the objects in list? While we saw ForEach was reference type on value type
Regardless of whether the type of c is a reference type or a value type, when setting a variable c = something, you are overwriting whatever the variable referred to. So the original object that c referred to is no longer referenced. This does not change the list from updating its reference either though, that’s simply not how it works.
If you want to replace some elements in your list by something else, you will need to use Select:
list.Select(c =>
{
if (SomeCondition)
return new SomeClass();
// default case, return the same element
return c;
}.ToList();
Note that this creates a new list, so the old list still contains the same elements.
If you wanted to actually replace elements in the original list, you will have to overwrite the elements in the list by accessing its index. You can do this with a normal for loop:
for (int i = 0; i < list.Count; i++)
{
if (SomeCondition)
{
list[i] = new SomeClass();
}
}
This will actually mutate the existing list and replace some elements inside of it.
I've considered 2 cases:
var a = new { a = 5 };
var b = new { a = 6 };
Console.WriteLine(a.GetType() == b.GetType()); // True
Ideone: http://ideone.com/F8QwHY
and:
var a = new { a = 5, b = 7 };
var b = new { b = 7, a = 6 };
Console.WriteLine(a.GetType() == b.GetType()); // False
Ideone: http://ideone.com/hDTcxX
The question is why does order of fields actually matter?
Is there any reason for this or it's just simply because it is (such is the design).
If the reason is just that anonymus types are not supposed to be used this way and you are not supposed to appeal to GetType, then why does compiler re-use a single class in first case and not just generate a new class for each anonymus type declaration?
So the reason for the design decision was ToString. An anonymous type returns a different string accoding to the order. Read Eric Lippert's blog.
{ a = 5, b = 7 }
{ b = 7, a = 6 }
Demo
C# language specification, section 7.6.10.6, requires the sequence of properties to be the same in order for the anonymous types to be considered identical:
Within the same program, two anonymous object initializers that specify a sequence of properties of the same names and compile-time types in the same order will produce instances of the same anonymous type.
In your second example, the first anonymous class has the sequence of properties {a, b}, while the second anonymous class has the sequence {b, a}. These sequences are not considered to be the same.
You lead on to what I'm guessing the reason is: the types are anonymous so depending on GetType() to return reliable results is a terrible idea.
As for why the compiler re-uses a type if the order matches, I'm guessing it's simply to save time and space. When you take order into account, it's far easier to cache generated classes during compilation and then re-use them when needed.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Use of var keyword in C#
Being relatively new to C# I was wondering the motivation MS had to introduce the var implicit typed variables. The documentation says:
An implicitly typed local variable is strongly typed just as if you
had declared the type yourself, but the compiler determines the type.
Some lines further:
In many cases the use of var is optional and is just a syntactic
convenience
This is all nice but in my mind, this will only cause confusion.
Say you are reviewing this for loop.
foreach (var item in custQuery){
// A bench of code...
}
Instead of reviewing the content and the semantics of the loop, I would loose precious time looking for the item's type!
I would prefer the following instead:
foreach (String item in custQuery){
// A bench of code...
}
The question is: I read that implicit typed variables help when dealing with LINQ, does really help to use it in other scenarios?
The var keyword was needed when LINQ was introduced, so that the language could create a strongly typed variable for an anonymous type.
Example:
var x = new { Y = 42 };
Now x is a strongly typed variable that has a specific type, but there is no name for that type. The compiler knows what x.Y means, so you don't have to use reflection to get to the data in the object, as you would if you did:
object x = new { Y = 42 };
Now x is of the type object, so you can't use x.Y.
When used with LINQ it can for example look like this:
var x = from item in source select new { X = item.X, Y = item.Y };
The x variable is now an IEnumerable<T> where T is a specific type which doesn't have a name.
Since the var keyword was introduced, it has also been used to make code more readable, and misused to save keystrokes.
An example where it makes the code more readable would be:
var list =
new System.Collections.Generic.List<System.Windows.Forms.Message.Msg>();
instead of:
System.Collections.Generic.List<System.Windows.Forms.Message.Msg> list =
new System.Collections.Generic.List<System.Windows.Forms.Message.Msg>();
This is a good use of the var keyword, as the type already exists in the statement. A case where the keyword can be misused is in a statement like:
var result = SomeMethod();
As the SomeMethod name doesn't give any indication of what type it returns, it's not obvious what the type of the variable will be. In this case you should write out the type rather than using the var keyword.
I think some of the motivation was to allow something like this -
List<int> list = new List<int>();
to be turned into this -
var list = new List<int>();
The second example is shorter and more readable, but still clearly expresses the intent of the code. There are instances when it will be less clear, but in lots of situations you get conciseness with no loss of clarity.
var is really needed for anonymous types, which are used in Linq a bit:
var results =
from item in context.Table
select new {Name=item.Name, id=item.id};
Since the collection is of an anonymous type, it can not be named. It has a real type, but not one with a name before compilation.
I'm returning a Json'ed annonymous type:
IList<MyClass> listOfStuff = GetListOfStuff();
return Json(
new {
stuff = listOfStuff
}
);
In certain cases, I know that listOfStuff will be empty. So I don't want the overhead of calling GetListOfStuff() (which makes a database call).
So in this case I'm writing:
return Json(
new {
stuff = new List<ListOfStuff>()
}
);
which seems a bit unnecessarily verbose. I don't care what type of List it is, because it's empty anyway.
Is there a shorthand that can be used to signify empty enumerable/list/array? Something like:
return Json(
new {
stuff = new []
}
);
Or have I been programming JavaScript too long? :)
Essentially you want to emit an empty array. C# can infer the array type from the arguments, but for empty arrays, you still have to specify type. I guess your original way of doing it is good enough. Or you could do this:
return Json(
new {
stuff = new ListOfStuff[]{}
}
);
The type of the array does not really matter as any empty enumerable will translate into [] in JSON. I guess, for readability sake, do specify the type of the empty array. This way when others read your code, it's more obvious what that member is supposed to be.
You could use Enumerable.Empty to be a little more explicit:
return Json(
new {
stuff = Enumerable.Empty<ListOfStuff>()
}
);
Although it isn't shorter and doesn't get rid of the type argument.
dynamic is also a better option when dealing with an anonymous type
Enumerable.Empty<dynamic>()
this worked well for me
You might not care what type of list it is, but it matters to the caller. C# does not generally try to infer types based on the variable to which it is being stored (just as you can't create overloads of methods on return type), so it's necessary to specify the type. That said, you can use new ListOfStuff[0] if you want an empty array returned. This has the effect of being immutable (in length) to the caller (they'll get an exception if they try to call the length-mutating IList<T> methods.)
Yes, there is. You have to define an array with as least one element, and use linq to filter the array leaving no elements. Example:
var foo = new
{
Code = 1,
Name = "Bar",
Value = (float?)5.0
};
//use an empty object (or any object) to define the type of the array
var emptyArrayOfFooType = new[] {
new
{
Code = (int)0,
Name = (string)null,
Value = (float?)null
}
}.Where(e => false).ToArray(); //use linq to filter the array leaving no elements
//you can use an existing anonymous type variable too
var anotherEmptyArray = new[] { foo }.Where(e => false).ToArray();
//this array with one element has the same type of the previous two arrays
var fooArray = new[] { foo };
//all arrays have the same type, so you can combine them
var combinedArrays = emptyArrayOfFooType.Concat(anotherEmptyArray).Union(fooArray);
send a generic type?:
List<Object>()
or send an empty object array: new Object[0]
I guess you are talking about C# here. My knowledge is limited in C# but I don't think you can create a new object with no type. Why can't you return a generic new List[] ? (might be mixing Java generics here, am not sure is one can return a generic type list in C#).