With the inception of the dynamic type and the DLR in .NET 4, I now have 3 options when declaring what I call "open" types:
var, locally implicit types to emphasize the 'what' instead of the 'how',
object, alias for System.Object, and
dynamic, disable compiler checks, adding methods/properties at runtime
While there's a lot written about these out there, nothing I've found puts them together, and I have to confess, it's still a bit fuzzy.
Add to this LINQ, lambda expressions, anonymous types, reflection... and it gets more shaky.
I'd like to see some examples, perhaps contrasting advantages/disadvantages, to help me solidify my grasp of these concepts, as well as help me understand when, where and how I should pick between them.
Thank you!
Use var to keep your code short and more readable, or when working with anonymous types:
var dict = new Dictionary<int, List<string>>();
var x = db.Person.Select(p => new { p.Name, p.Age });
Use dynamic when dynamic binding is useful, or required. Or when you need to decide which method to call based on the runtime type of the object.
Use object as little as possible, prefer using specific types or generics. One place where it's useful is when you have object used just for locking:
object m_lock = new object();
lock (m_lock)
{
// do something
}
var is exactly the same as writing the full type, so use that when a variable should be of a single type. It is often used with LINQ since you often use anonymous types with LINQ.
object is the root of all classes, and so should be used when a variable will have many different, unrelated/not inherited instances, or when you do not know the type ad compile time (e.g. reflection). It's use should generally be avoided if possible.
dynamic is for objects that are dynamic in nature, in that they can have different methods and properties, these are useful for interacting with COM as well as dynamic languages and domain specific languages.
var: I use it for keeping code short:
instead of writing:
MyFramework.MyClass.MyType myvar = new MyFramework.MyClass.MyType();
i can keep it "short":
var myVar = new MyFramework.MyClass.MyType();
var is statically type so the Type is known at compile and runtime (so helps catch typos)
dynamic very much similar to objects but not limited as it would be with the Object methods, here the Type is inferred at runtime, it would be used in cases wherein you want to achieve some dynamic behaviour.
Well for object it ain't having any such members which you would be using, Generics would be more preferred in such cases
Have look on this article it gives advantages and limitations of Dynamic keyword.
Related
I ran into a problem while doing my job, which is porting software from flash AS3 to .NET/Mono. In AS3 code base I can find many Object declarations that are initialized like this:
private const MAPPING:Object =
{
ssdungf:'flydung',
ssdungt:'flydung',
superfutter:'superfeed'
}
The best option for me would be in C# using anonymous type like this:
var MAPPING = new
{
ssdungf = "flydung",
ssdungt = "flydung",
superfutter = "superfeed"
};
The problem is... well let me quote MSDN (source):
You cannot declare a field, a property, an event, or the return type of a method as having an anonymous type
But they don't say why.
So the question remains: why you cannot declare a field and property as having an anonymous type? Why .NET creators stripped it from that option?
I am getting warning here from SO that my question appears subjective, but I think it is not at all - there need to be objective reason for that.
As for me, I don't see any obstacles for that but somehow it is not supported. As compiler can easily generate the type for field or property of class, in a same manner as it does for local variables.
The option for me was to use dynamic type but unfortunately Mono engine I am using is stripped from that.
Also the option for me is to use object type and using later reflection to find these fields:
private static readonly object MAPPING = new
{
ssdungf = "flydung",
ssdungt = "flydung",
superfutter = "superfeed"
};
But using reflection is this situation is dirty I would say.
I tried to find answer, but I really didn't find any. Here are some SO answers to similar questions, but they don't answer why:
Can a class property/field be of anonymous type in C# 4.0?
Declaring a LIST variable of an anonymous type in C#
How do you declare a Func with an anonymous return type?
Why you cannot declare a field and property as having an anonymous type?
Because C# is statically typed, so any memory location has to be given a type, and declaration does so. With locals we can infer from context if its initialised at the same time as declaration with var but that is a shorthand for a type that is usable even when the type hasn't got a name.
What would a field with an anonymous type, that is to say a statically-bound but indescribable type, mean?
dynamic would indeed be the closest analogy to the code you are porting, but since that isn't available to you, you might consider using an IDictionary<string, object> (which incidentally is how ExpandoObject, which is often used with dynamic to have objects that behave more like javascrpt objects, works behind the scenes). This would be slower and less type-safe than if you created a class for the object needed, but can work.
The problem on an anoynmous property is: how do you get/set it?
Suppose it would work:
class MyClass
{
public MyField = new { TheValue = "Hello World" };
}
Now in your consuming code you´d write code to read the code:
MyClass m = new MyClass();
m.MyField.TheValue = "newValue";
How was this different from having a type for MyField? All you´d get is that you can omit two or three lines of code whilst gaining nothing. But I think you might produce many problems as no-one knows what he can assign to/expect from that member.
Furthermore you can´t do much with an anonymous object, basically you can just set it and read it. There are no methods (except Equalsand GetHashCode inherited from object) that you can call so the opportunities are quite low.
Last but not least an anonymous object is usually used as temporaryily, for example within a Select-statement. When you use it you say: this type is going to be used only within the current specific scope and can be ignored by the entire world as internal implementation-detail. Creating a property of an anonymous type will expose such a detail to the outside. Of course you could argue that the designers could at least allow them for private members, but I guess doing so would bypass the complete concept of accessability for nothing.
In C#, I would like to figure out if it's possible to declare an anonymous type where the fields are not known until run-time.
For example, if I have a List of key/value pairs, can I declare an anonymous type based on the contents of that list? The specific case I'm working with is passing parameters to Dapper, where I don't know ahead of time how many parameters I will have.
List<Tuple<string, string>> paramList = new List<Tuple<string, string>>() {
new Tuple<string, string>("key1", "value1"),
new Tuple<string, string>("key2", "value2")
...
};
I'd like to convert this List (or an equivalent Map) into an anonymous type that I can pass to Dapper as query parameters. So ideally, the above list would wind up looking like this, if defined as an anonymous type:
new { key1=value1, key2=value2, ... }
I've seen several questions on StackOverflow asking about extending anonymous types after they are declared ("extendo objects"), or declaring arbitrary fields on an object after it's created, but I don't need to do that... I just need to declare the types dynamically up-front once. My suspicion is that it will require some fancy reflection, if it's possible at all.
My understanding is that the compiler defines a type for anonymous classes under the hood at compile-time, so if the fields of that class are not available until run-time, I might be out of luck. My use case may in fact be no different in actuality than using an "extendo object" to define arbitrary fields, whenever.
Alternatively, if anyone knows of a better way to pass query parameters to Dapper (rather than declaring an anonymous class), I would love to hear about that as well.
Thanks!
UPDATE
Sorry for the delay in getting back to this one! These answers were all great, I wish I could give points to everyone. I ended up using jbtule's solution (with edit by Sam Saffron), passing IDynamicParameters to Dapper, so I felt I had to give the answer to him. The other answers were also good, and answered specific questions that I had asked. I really appreciate everyone's time on this!
Dapper's creators were very aware of this problem. This kind of functionality is really needed for INSERT and UPDATE helpers.
The Query, Execute and QueryMultiple methods take in a dynamic parameter. This can either be an anonymous type, a concrete type or an object that implements IDynamicParameters.
public interface IDynamicParameters
{
void AddParameters(IDbCommand command, Identity identity);
}
This interface is very handy, AddParameters is called just before running any SQL. Not only does this give you rich control over the parameters sent to SQL. It allows you to hook up DB specific DbParameters, since you have access to the command (you can cast it to the db specific one). This allows for support of Table Values Parameters and so on.
Dapper contains an implementation of this interface that can be used for your purposes called DynamicParameters. This allows you to both concatenated anonymous parameter bags and add specific values.
You can use the method AddDynamicParams to append an anonymous type.
var p = new DynamicParameters();
p.AddDynamicParams(new{a = "1"});
p.AddDynamicParams(new{b = "2", c = "3"});
p.Add("d", "4")
var r = cnn.Query("select #a a, #b b, #c c, #d d", p);
// r.a == 1, r.b == 2, r.c == 3, r.d == 4
In C#, I would like to figure out if it's possible to declare an anonymous type where the fields are not known until run-time.
Anonymous types are generated by the compiler. You want to know if the compiler will generate you a compiler-generated type with field types not known to the compiler. Clearly it cannot do so; as you correctly surmise, you are out of luck.
I've seen several questions on StackOverflow asking about extending anonymous types after they are declared ("extendo objects")
We usually call those "expando" objects.
If what you want to do is make an expando object based on a dictionary of key-value pairs, then use the ExpandoObject class to do that. See this MSDN article for details:
http://msdn.microsoft.com/en-us/magazine/ff796227.aspx
If what you want to do is generate a bona-fide .NET class at runtime, you can do that too. As you correctly note, you need some fancy reflection to do so. What you want to do is make a collectible assembly (so-called because unlike a normal assembly, you generate it at runtime and the garbage collector will clean it up when you are done with it.)
See http://msdn.microsoft.com/en-us/library/dd554932.aspx for details on how to make a collectible assembly and emit a type into it using a TypeBuilder.
You can't use an anonymous type. Anonymous types are generated by the compiler rather than at run-time. You could certainly use dynamic though:
dynamic dynamicObj = new ExpandoObject();
var objAsDict = (IDictionary<String, Object>)dynamicObj;
foreach(var item in paramList)
{
objAsDict.Add(item.Item1, item.Item2);
}
You can then use dynamicObj as a regular object:
Console.WriteLine(dynamicObj.key1); // would output "value1"
What is the design decision to lean towards not returning an anonymous types from a method?
You can return an instance of an anonymous type from a method - but because you can't name it, you can't declare exactly what the method will return, so you'd have to declare that it returns just object. That means the caller won't have statically typed access to the properties etc - although they could still pass the instance around, access it via reflection (or dynamic typing in C# 4).
Personally I would quite like a future version of C# to allow you to write a very brief class declaration which generates the same code (immutable properties, constructor, Equals/GetHashcode/ToString) with a name...
There is one grotty hack to go round it, called casting by example. I wouldn't recommend it though.
Because an anonymous type has no name. Therefore you cannot declare a return type for a method.
Because C# is statically typed language and in a statically typed language the return type of a method needs to be known at compile time and anonymous types have no names.
How can you use your type inside your method if the definition is only in the call of the method ?
It's not javascript.
A lot of answers heere seem to indicatie that it is not possible because of the current syntax and rule. But the question is about changing them. I think it would be possible, but a little complicated and resulting in an awkward (error-prone) syntax. Like
var f() { return new { A = "*", B = 1 }; }
var x = f();
The question is whether this adds sufficient value to the language to make it worth it.
At least up to 3.5, anonymous types are actually resolved at compile time, and this would be impossible (or quite hard) to do with anonymous method signatures.
This question already has answers here:
Closed 13 years ago.
Duplicate:
What to use var or object name type
I couldn't understand the need of var keyword in C# 3.0 What is the advantage in using it.
i saw this question but did not understand the real purpose of using it
It's mostly present for LINQ, when you may use an anonymous type as the projection:
var query = from person in employees
where person.Salary > 10000m
select new { FullName=person.Name, person.Department };
Here the type of query can't be declared explicitly, because the anonymous type has no name. (In real world cases the anonymous type often includes values from multiple objects, so there's no one named class which contains all the properties.)
It's also practically useful when you're initializing a variable using a potentially long type name (usually due to generics) and just calling a constructor - it increases the information density (reduces redundancy). There's the same amount of information in these two lines:
List<Func<string, int>> functions = new List<Func<string, int>>();
var functions = new List<Function<string, int>>();
but the second one expresses it in a more compact way.
Of course this can be abused, e.g.
var nonObviousType = 999999999;
but when it's obvious what the type's variable is, I believe it can significantly increase readability.
The primary reason for its existence is the introduction of anonymous types in C#. You can construct types on the fly that don't have a name. How would you specify their name? The answer: You can't. You just tell the compiler to infer them for you:
var user = users.Where(u=> u.Name == "Mehrdad")
.Select(u => new { u.Name, u.Password });
It's a shorthand way of declaring a var. Although "int i = new int()" isn't too much to type, when you start getting to longer types, you end up with a lot of lines that look like:
SomeReallyLong.TypeName.WithNameSpaces.AndEverything myVar = new SomeReallyLong.TypeName.WithNameSpaces.AndEverything();
It eventually occurred to someone that the compiler already knew what type you were declaring thanks to the information you were using to initialize the var, so it wouldn't be too much to ask to just have the compiler do the right thing here.
Here are a couple of advantages
Less typing with no loss of functionality
Increases the type safety of your code. A foreach loop using an iteration variable which is typed to var will catch silently casts that are introduced with explicit types
Makes it so you don't have to write the same name twice in a variable declaration.
Some features, such as declaring a strongly typed anonymous type local variable, require the use of var
Shameless self promotion. I wrote a blog entry on this subject awhile back that dived into when I thought the use of var was appropriate and contains relative information to this topic.
http://beta.blogs.msdn.com/jaredpar/archive/2008/09/09/when-to-use-type-inference.aspx
Linq expressions don't return a predefined type, so you need a 'generic' variable declaration keyword to capture that and other places where anonymous types are used.
Used carefully, it can make refactoring easier by decoupling a method's return type from the variable that captures it.
Having to put the same name on the same line twice for the same statement is really kind of silly. It's a pain to type something like this:
.
ReallyLongTypeName<SomeOtherLongTypeName> MyVariable = new ReallyLongTypeName<SomeOtherLongTypeName>();
In short:
minimize the need for typing the variable type twice
essential in supporting anonymous types, e.g. as returned by LINQ queries
The real need for the var keyword was to support anonymous types in C# 3.0--which in turn were required to properly support LiNQ (Language Integrated Querying).
Without using var you could never do something like this:
var person = new { Name = "Peter", Age=4};
Which means that you couldn't execute execute the following linq query because you wouldn't know how to assign it to a variable:
[var/sometype] dogsFixedQuery = from myDog in kennel select new {dogName = myDog.FirstName + " " + myDog.OwnerLastName, myDog.IsNeutered, dogLocation = kennel.Address};
The utility of anonymous types will be more apparent if you start to create more complex linq queries with multiple levels of returns and joins.
The fact that you can use var in other ways to avoid typing out something like IEnumerable<Dictionary<List<string>,IOrderedCollection<DateTime>> myBadDesign = getBadDesignController().BadDesignResults("shoppingCart");
is just a side-effect/bonus in case you're a lazy typer =)
There are cons for readability if you start calling vars in disparate locations but if you're using var for a strong type and the compiler can determine the type of your variable than any reader should be able to determine it as well.
This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
What’s the point of the var keyword?
Hello everyone,
I want to confirm whether my understanding is correct. If I do not use LINQ, then the only benefit of using var is to make brevity? Is that correct understanding?
No, you can use var to construct anonymous types, regardless of whether or not you're using LINQ:
var anon = new { Name = "Anonymous", Age = 42 };
It's also easier for working with types like this. When you have very long generic types, the type name can get in the way of visually identifying the variable name as part of a declaration.
Dictionary<string, Dictionary<int, ICollection<object>>>
especially if you go back through and change it to
Dictionary<string, IDictionary<int, ICollection<object>>>
From msdn:
Beginning in Visual C# 3.0, variables
that are declared at method scope can
have an implicit type var. An
implicitly typed local variable is
strongly typed just as if you had
declared the type yourself, but the
compiler determines the type. The
following two declarations of i are
functionally equivalent:
var i = 10; // implicitly typed
int i = 10; //explicitly typed
MSDN Link Here
If you're not using LINQ, var allows you to only declare the type of the variable once, instead of twice.
Example
var myObject = new MyObject();
vs
MyObject myObject = new MyObject();
This can only be done locally, and is also useful for declaring anonymous types.
Example
var myAnon = new { Name = "Something", Count = 45 };
Other than for LINQ queries I would be very cautious in using the var keyword. There are specific instance when you just need an anonymous type but this is few and far between I think. Var can lead to very confusing code as you have no idea what the type you are dealing with when reading the code unless you use the intellisense crutch.
It worries me more and more that I see so many snippets and bits of code that do the following... it's lazy and not what the var keyword was intended for:
// Not too bad but still shouldn't be done because the only gain you have is keystrokes
var Something = new SomeObject();
// Type here is not obvious, are you getting an int, double, custom object back???
var Something = GetLengthOfSpaghettiCode();
So use it for LINQ... use it for anonymous types (if you do use anonymous types outside of LINQ you should really scrutinize why you need to).
Quote from MSDN (very last line of article) regarding use of var:
However, the use of var does have at least the potential to make your code more difficult to understand for other developers. For that reason, the C# documentation generally uses var only when it is required.
Don't use it as a short cut to save keystrokes, the next guy looking at your code will appreciate it.
Pretty much, yes. var may be used wherever the compiler can infer the type of the variable from whatever value you are assigning to it. (The type inference rules are quite complex however, so you may want to read the C# specification for a full understandin.)
It's not quite correct in that the var keyword is required for defining anonymous types. For example:
var foo = new { abc = 1, def = 2 };
which can be used outside of LINQ queries as well as inside, of course.
I don't think using var should be a problem - and I prefer it for exactly the reasons of code readability. First of all, var is only syntactic sugar and just gets compiled away to a proper type when IL is emitted. And as far as the code readability goes, it makes more sense to focus on the purpose the variable is used for, and how it is assigned than just its type. VS .NET editor shows the type in the line following it anyway - if you just hover on it. So this shouldn't be a problem at all. And as far as the debugging goes - if you see Autos/Local/Watch windows - they display the types of all the members.
It makes more sense for me to see code like this:
var customers = GetCustomerList();
foreach (var customer in customers)
{
customer.ProcessOrders();
}
as opposed to
List<CustomerObjectDeserializedFromWebService> customers = GetCustomers();
foreach (CustomerObjectDeserializedFromWebService customer in customers)
{
customer.ProcessOrders();
}
var is in its fairness limited to using in local variable declarations which are also initialized at the time of declaration. And in that one case, if you omit the actual type it definitely improves readability IMO.
EDIT: And it would unfair on my part not to warn against the usages as below:
var x = 20;
This is not good; when the literal is applicable to multiple types, you need to know the default type of the literal and hence understand what is infered for the type of x. Yes, by all means, I would avoid such declarations.
I believe it is also used in the WCF (Windows communication Foundation) when dealing with data obtained via webservices and the like.
I've also found that the use of var also eases refactoring in low-coupled designs. This is because we tend to strong type variables, but normally the code that follows is expecting weaker types. Using var you'll offset type changes to the compiler.