This question already has answers here:
Use of var keyword in C#
(86 answers)
Closed 8 years ago.
I have an object animal:
class Animal{
}
I want to create an object of Animal, is there a difference between the lines on the class main?
class main{
var myVar = new Animal(); // case 1
Animal myAnimal = new Animal(); // case 2
}
There is no difference. MSDN var description 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 other words, it is just a helpful way of writing the same code, with a little help of compiler. It is quite usefull when you are creating long types like:
var dict = new Dictionary<string, List<int>>();
instead of:
Dictionary<string, List<int>> dict = new Dictionary<string, List<int>>();
but was added at the same time as LINQ and anonymous types to make LINQ queries:
var outpus = someList.Where(x => x.SomeData == 0)
.Select(new
{
FieldA = x.SomeField
});
so here compiler determines the anonymous type, you do not have to specify it.
You can read more about it on MSDN.
Related
This question already has answers here:
What's the difference between an object initializer and a constructor?
(8 answers)
Closed 7 years ago.
I have the following class:
public class TestClass {
public string ClassName {
get;
set;
}
}
What's the difference between doing:
var instance = new TestClass();
and doing
var instance = new TestClass { };
I thought you needed to include the () to call the object's constructor. What does that mean?
Edit: Can someone explain which is best? Or if one ignores the constructor, benefits or disadvantages?
Edit2: Sorry if I asked something that was already answered. The difference was somewhat clear to me, but I really didn't understand how I could mix and match () and {}, since sometimes the () are ignored and I wanted to know when I could do so
The first example instantiates a new instance.
The second example instantiates a new instance via object initialization syntax.
They both end up creating a new instance.
You would use the latter if you needed or wanted to set a public property or field of your class during instantiation:
var instance = new TestClass { ClassName = "TestingInstance" };
as opposed to
var instance = new TestClass();
instance.ClassName = "TestingInstance";
It is essentially "syntactic sugar" that makes your life a bit easier (and for some devs more explicit) when creating new objects and setting a lot of properties.
When using object initialization, the params () are optional but the braces {} and statement-ending semi-colon ; are required
The second piece of code is shorthand syntax for object initialization.
You would use the second syntax when you want to set properties on the object at the same time, like this:
var x = new SomeObject
{
Property1 = "What's this?",
Property2 = 42
};
You can combine as well:
var x = new SomeObject("Some constructor parameter", 17, true)
{
OtherProperty = 42
};
The code can be loosely translated to this:
var temp = new SomeObject("Some constructor parameter", 17, true);
temp.OtherProperty = 42;
var x = temp;
The second example, with the {}, allows you to set public properties and fields on the object. For instance:
System.Drawing.Point p = new System.Drawing.Point
{
X = 3,
Y = 5
};
There's little reason to use {} over () when there's nothing inside the {}.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I pass an anonymous type to a method?
I have the following LINQ Statement, whose output has to be processed in another method:
var data = from lines in File.ReadAllLines(TrainingDataFile)
.Skip(ContainsHeader ? 1 : 0)
let f = lines.Split(new[] { FieldSeparator }).ToList<String>()
let target = f[TargetVariablePositionZeroBased]
select new { F=f, T=target };
What should be the datatype of the parameter in the method that will take this data?
You can not return the anonymous data types from a method. You can define a class and return object of that class from query and pass it to target method.
public class SomeClass
{
public string F {get; set;}
public string T {get; set;}
}
var data = from lines in File.ReadAllLines(TrainingDataFile)
.Skip(ContainsHeader ? 1 : 0)
let f = lines.Split(new[] { FieldSeparator }).ToList<String>()
let target = f[TargetVariablePositionZeroBased]
select new SomeClass { F=f, T=target };
You can pass the query result IEnumerable<SomeClass> to method as parameter.
public void MethodToCall(IEnumerable<SomeClass> someClass)
{
}
To call the method by passing the query result (IEnumerable<SomeClass>) that is stored in data in this sample code
MethodToCall(data);
You can't very easily pass anonymous types around. You can either create a class, or since your data has only two properties, use a Tuple:
select new Tuple<List<string>, string> (f, target);
If I have the data types correct, then the data type of the parameter would be:
IEnumerable<Tuple<List<string>, string>>
and you would reference F and T using the Tuple properties Item1 and Item2.
1) Just to pass the result of the query, make your function generic, that will do:
var data = from lines in File.ReadAllLines(TrainingDataFile)
.Skip(ContainsHeader ? 1 : 0)
let f = lines.Split(new[] { FieldSeparator }).ToList<String>()
let target = f[TargetVariablePositionZeroBased]
select new { F=f, T=target };
SomeMethod(data);
public void SomeMethod<T>(IEnumerable<T> enumerable)
{
// ^^choose the return type..
}
Simple. If the processing inside the method is something so simple this will do. But you won't be able to access properties F and T inside the method.
To do so:
2) You can use the "cast by example" trick shown here by Eric. To quote him:
We use method type inference and local variable type inference to tell
the compiler "these two things are the same type". This lets you
export an anonymous type as object and cast it back to anonymous type.
...the trick only works if the example and the source objects were
created in code in the same assembly; two "identical" anonymous types
in two different assemblies do not unify to be the same type.
SomeMethod(data);
public void SomeMethod(IEnumerable<object> enumerable)
{
var template = new { F = new List<string>(), T = string.Empty };
foreach (var item in enumerable)
{
var anonymousType = item.CastToTypeOf(template);
//print string.Join(", ", anonymousType.F) + " - " + anonymousType.T //compiles
//or whatever
}
}
//a more generic name perhaps is 'CastToTypeOf' as an extension method
public static T CastToTypeOf<T>(this object source, T example) where T : class
{
return (T)source;
}
The catch here is that SomeMethod now is tailor made for your anonymous type, since you're specifying a specific type inside the method, so its better to not make the function generic (though you can do) and to give a suitable name for the function.
3) If function is just for your unique type now, I would better have them all wrapped in a single method and not pass at all - no hassle! :)
4) Or you can delegate the action to be done on your anonymous type. So method signature would be like:
SomeMethod(data, d => print string.Join(", ", d.F) + " - " + d.T);
public void SomeMethod<T>(IEnumerable<T> enumerable, Action<T> actor)
{
foreach (var item in enumerable)
actor(item);
}
If it matters you can have Func delegate as well by having one more type argument.
5) Rely on fiddly reflection to get the properties from your anonymous type otherwise.
6) Use dynamic keyword on method argument and now you have dynamic typing. Both the above doesnt give you benefits of static typing.
7) You will be better off having a separate class that holds F and T. And that the best of all. But ask yourself do they together represent something as an entity?
8) If not, just pass an IEnumerable<Tuple> or IDictionary depending on what matters.
It all depends on what/how you want to achieve with the method. Personally, I would go for the approach 2 in a hobby project (for the fun involved), but in production code 3, 4, 7, 8 depending on the context.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I pass an anonymous type to a method?
Im trying to recognize the type of the anonymous type.
List<int> lst = new List<int> {1, 2, 3, 4, 5};
var myVarType = from item in lst select new {P = item*item, P2 = item + "###"};
foreach (var k in myVarType)
{
Console.WriteLine(k.P + " " + k.P2);
}
Now i want a part of code to be transferred to a function but it screams that he doesnt know the type - which is logical since var is to be known at compile time and he doesnt know the type at compile :
I dont want to use dynamic || Tuples.
and as you know var is not acceptable as a func param type.
But , Ive once read that there is a trick which lets me transfer to myFunc the anonymous type .
I think it was by Jon skeet or Eric lippert.
Help ?
edit
look at my self answer.
I found it here
What's the return type of an anonymous class
The type is 'generated' and you might be able to get it at run-time with reflection but it will contain characters you can't use in a name.
You could use Tuples:
select new Tuple<int,string> ( item*item, item + "###");
Make the method generic, this should work.
static void MyFunc<T>(IEnumerable<T> myVarType) ...
Edit
As mentioned in comments you can't access the properties. You could use here a delegate to access the properties or use dynamic ( which you don't want to use ).
static void MyFunc<T>(IEnumerable<T> myVarType, Func<T, Object[]> argumentCreator)
{
Console.WriteLine("{0} {1}", argumentCreator(myVarType));
}
here is the code which i found
What's the return type of an anonymous class
static T CastByExample<T>(object source, T example) where T : class
{
return source as T;
}
static object ReturnsAnonymous() { return new { X = 123 }; }
static void DoIt()
{
object obj = ReturnsAnonymous();
var example = new { X = 0 };
var anon = CastByExample(obj, example);
Console.WriteLine(anon.X); // 123
}
This question already has answers here:
How to create a new object instance from a Type
(11 answers)
Programmatic equivalent of default(Type)
(14 answers)
Closed 9 years ago.
With generics you can
var object = default(T);
But when all you have is a Type instance I could only
constructor = type.GetConstructor(Type.EmptyTypes);
var parameters = new object[0];
var obj = constructor.Invoke(parameters);
or even
var obj = type.GetConstructor(Type.EmptyTypes).Invoke(new object[0]);
Isn't there a shorter way, like the generics version?
The closest available is Activator.CreateInstance:
object o = Activator.CreateInstance(type);
... but of course this relies on there being a public parameterless constructor. (Other overloads allow you to specify constructor arguments.)
I've used an explicitly typed variable here to make it clear that we really don't have a variable of the type itself... you can't write:
Type t = typeof(MemoryStream);
// Won't compile
MemoryStream ms = Activator.CreateInstance(t);
for example. The compile-time type of the return value of CreateInstance is always object.
Note that default(T) won't create an instance of a reference type - it gives the default value for the type, which is a null reference for reference types. Compare that with CreateInstance which would actually create a new object.
var myObject = Activator.CreateInstance(myType)
You have to cast if you want to use a typed parameter:
User user = (User)Activator.CreateInstance(typeof(User));
.. or with parameters
User user = (User)Activator.CreateInstance(typeof(User), new object[]{firstName, lastName});
You can also use generics:
public T Create<T>() where T : class, new()
{
return new T();
}
var user = Create<User>();
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Difference between “var” and “object” in C#
I would like to know the difference between var and object.
When to use Var and when to use Object.
Pros and cons of using them.
var is just shorthand for "let the compiler pick the right variable type for me" (compile-time type-inference is the more exact term).
object, on the other hand, is a specific type; all other reference types derive from object, so you can assign anything to a variable of type object.
var is the answer when you find yourself asking, do I really have to type that long type name twice, in e.g.:
Dictionary<string, Func<List<Func<int, int, double>>, IEnumerable<Tuple<double, string>>>> myDict = new Dictionary<string, Func<List<Func<int, int, double>>, IEnumerable<Tuple<double, string>>>>();
Why no friend, you don't. Use var instead:
var myDict = new Dictionary<string, Func<List<Func<int, int, double>>, IEnumerable<Tuple<double, string>>>>();
Now myDict really is a Dictionary<string, Func<List<Func<int, int, double>>, IEnumerable<Tuple<double, string>>>>, so you can add things to it, enumerate it, etc.
If you declared it as object you couldn't do any operations with it that are provided by Dictionary, only the ones valid for all objects.
var is still strongly typed but with object you will have to cast everything.
var foo = "Hello, I am a string!";
// foo is a string, so this compiles
var fooCharArray = foo.ToCharArray();
object bar = foo;
// bar is not a string, so this does not compile
var barCharArray = bar.ToCharArray();
In the first example, the compiler knows that foo is a string and so we can call string methods on foo.
In the second example, we "upcast" the string foo to an object. Now the compiler does not know (because it shouldn't know!) that bar is actually a string, and we cannot call string methods on bar. The compiler will not allow implicit downcasting from an object (or any base type) to a derived type (such as System.String). Its part of compile time type safety rules.