In c#, you have the object keyword to denote any data type, which is very helpful for dynamism. Is there an equivalent of this is go?
Basically, I want to have
Dictionary<string, object>
but in go, which I presume would be something like:
Data := make(map[string]object)
But my IDE doesn't recognize object as a thing. Any solve would be appreciated.
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"
At first I thought something like:
var aName=getAllSomethings();
Is very unreadable, and so I'll use dynamic typing just when there's no room for confusion such as:
AClassName aName = new AClassName();
Here,
var aName=new AClassName();
seems readable.
But than I read (here) that dynamic typing also comes with a price in performance.
I tried reading all the other posts in that link to understand where I should use dynamic typing, but couldn't come up with even one good reason. Should I just wait for when I'll tell myself - "This can only be solved with dynamic typing" ? Or are there better (practical) reasons for using it?
Thanks.
Edit: My mistake (-: will close this question ASAP.
var isn't dynamic typing. It's just that the type of aName is inferred by the compiler.
Your example is still entirely statically typed, and has no performance penalty. Your code is compiled into exactly the same IL as it would be with an explicit type name.
Now in C# 4, dynamic typing does exist, but it would be written as:
dynamic aName = new AClassName();
My personal belief is that dynamic typing will be relatively rarely useful in C# 4 - basically when you're dealing with data which is already only known dynamically, e.g. reflection, or navigating XML.
This is not dynamic typing. The var declares a static type known at compile time and it will be absolutely equivalent to declaring the type name. The compiler will infer the type and replace it in the resulting assembly.
Using the var keyword isn't dynamic typing. The var keyword is handled by the compiler. The variable gets statically typed based on the first assignment to the variable.
The type of:
var value = new StringBuilder();
Is StringBuilder. There's no way to change that type (which is what dynamic typing would allow).
What Jon Skeet is referring to in his blog is the dynamic keyword. That is a whole other beast.
That isn't dynamic typing. Dynamic typing is through the "dynamic" type (oddly enough). Using var has no overhead at all, it is a coding shorthand that still produces strongly typed variables.
You are misunderstaninf why dynamic typing is.
"var" uses Type Inference to deduce at compile time the type of the variable. It's mechanism is fairly straighforward, and has absolutely no performance impact. A variable declared with "var" can still only be one exact type (or derivations of that type).
Dynamic variables allow a variable to hold any type at runtime, and still perform operations on that object as if we know what is supports. Each of these calls makes the runtime perform a check to see if the method call is actually supported. That is part of why dynamic typing has a runtime overhead.
As everyone else has mentioned, the 'var' keyword does not give us dynamic typing. The type is inferred at compile time.
I use var when I think it makes sense; namely, when the type is obvious and it cuts down on the verbosity of a declaration:
var someDict = new Dictionary<string, int>();
Instead of...
Dictionary<string, int>() someDict = new Dictionary<string, int>();
However, in your example here:
var aName=getAllSomethings();
I wouldn't use 'var' because, as you have noticed already, you then have to check the return type of 'getAllSomethings()' (bad naming style for C# BTW) in order to know what 'aName' is, which just makes the code less readable.
I wanted to use the var keyword to declare a field in my class however var only seems to work inside methods.
The code I have looks like:
public static Dictionary<string, string> CommandList = new Dictionary<string, string>{};
and I wanted to have:
public static var CommandList = new Dictionary<string, string>
How come this isn't possible?
My article on the subject:
Why no var on fields?
To summarize:
If we have "var" fields then the type of the field cannot be determined until the expression is analyzed, and that happens after we already need to know the type of the field.
What if there are long chains, or even cycles in those references? All of those algorithms would have to be rewritten and tested in a world where top-level type information is being determined from them rather than being consumed by them.
If you have "var" fields then the initializer could be of anonymous type. Suppose the field is public. There is not yet any standard in the CLR or the CLS about what the right way to expose a field of anonymous type is.
From the C# reference
Beginning in Visual C# 3.0, variables
that are declared at method scope
can have an implicit type var.
Also from The C# Programming Reference
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.
var cannot be used on fields at class scope.
It just isn't intended for the usage you have in mind.
It's primary aim is to allow the support of anonymous types in your code, with the added advantage of allowing a nice terse way of specifying local variables.
The short answer is because the spec says it's not legal. ;-)
Generally, this is not what you want to do anyway. The type of the member should be IDictionary<string, string> not Dictionary<string, string>. It's a small nit but generally it's better to use an interface in an externally visible object so you can change the type later without affecting the clients of the code. The compiler is just giving you a little nudge to guide you that direction.
This question already has answers here:
Why would var be a bad thing?
(18 answers)
Closed 8 years ago.
I just installed a trial version of ReSharper and one of the first things I noticed is that it always suggests to replace explicitly typed local variables with implicitly typed ones, e.g:
public string SomeMethod(int aParam)
{
int aNumber = SomeOtherMethod(aParam);
// should be changed to:
var aNumber = SomeOtherMethod(aParam);
}
I think explicitly typed variables are more readable (more explicit).
What do you think about ReSharper's suggestion? Is there any advantage in using implicitly typed variables? When do you use implicit/explict vars?
I personally only use “var” when I can clearly distinguish the variable Type by just reading the declaration, for example:
var someVariable = new List<int>();
In the example above, its evident that “var” refers to “List<int>”.
I don’t like to use “var” when I have to go to some method definition to find out what variable type “var” represents or by having to rely on visual studio intelli-popup or whatever that is called, for example this in not ok to me:
var someVaraible = SomeMethod();
I mean, what is the “SomeMethod” function supposed to return? Can you tell just by looking at the line of code? No you can’t, so that is why I avoid using “var” on those situations.
There's a lot of discussion about this, but I think it all comes down to personal taste, just like using the 'this' keyword almost everywhere.
I personally prefer explictly typed variables, but when using nested generic collections things can become more readable using an implicitly typed variable. Look at:
Dictionary<string, Dictionary<string, string>> myDictionary = new Dictionary<string, Dictionary<string, string>>();
vs:
var myDictionary = new Dictionary<string, Dictionary<string, string>>();
EDIT: this SO topic covers the same topic, with some nice replies: What to use: var or object name type?
EDIT2: Working a lot with async nowadays, I find that using explicity typed variables can sometimes prevent nasty bugs. Consider this silly example where you would want to return the Id of a user. Also consider that GetUserAsync returns a Task<User>. If you use implicitly typed variables, you would end up using something like this:
public long GetUserId()
{
var user = GetUserAsync();
return user.Id;
}
This compiles, but it is wrong. 'user' is actually a Task<User>. And it compiles as Task also has an Id property. In this case, one would accidentally return the Id of a Task instead of the User.
public long GetUserId()
{
User user = GetUserAsync();
return user.Id;
}
The above does not compile, as the compiler will complain that you cannot cast a Task to a User. Adding the await keyword of course solves this.
I've actually had this happen to me once :-)
Just in case some haven’t noticed yet, you can easily change the “suggestions” in Reshaper (Reshaper -> Options -> Languages -> Context Actions -> “Replace explicit type specification with ‘var’”).
I personally prefer to have explicit type specifications everywhere, but I'm not too fussy about it.
It's just easier to type the var pseudo-keyword at times than a huge type name, especially if a generic could be involved. However, you should know they're functionally identical. There's no performance difference or anything either way. The compiler derives the type of the right-side of the assignment and replaces var with that type. It's not happening at run-time like a VB variant.
FWIW, the var keyword is plainly readable in many cases. Especially if...
The right-side of the assignment is a constructor expression.
var map = new Dictionary>();
Local variables have good names.
HTH