In "CLR via C#" book it's mentioned that dynamic keyword corresponding FCL type is System.Object. please clarify this .
It's not the same thing from the C#'s point of view at all... but in the compiled code, a variable declared as type dynamic will usually (possibly always) correspond with a CLR field or local variable of type object.
The C# compiler is responsible for making sure that any source code using that value has the dynamic behaviour applied to it. object is simply the compiler the representation uses for storage. It also applies the [Dynamic] attribute where appropriate, so that other code knows it's to be treated dynamically.
For example, consider this:
public class Foo
{
public dynamic someField;
}
I believe that will be compiled into IL equivalent to:
public class Foo
{
[Dynamic]
public object someField;
}
now if you write:
Foo foo = new Foo();
foo.someField = "hello";
Console.WriteLine(foo.someField.Length);
the compiler uses the attribute to know that foo.someField is dynamic, so the Length property should be dynamically bound.
From MSDN:
The type is a static type, but an object of type dynamic bypasses static type checking. In most cases, it functions like it has type object.
And:
Type dynamic behaves like type object in most circumstances. However, operations that contain expressions of type dynamic are not resolved or type checked by the compiler. The compiler packages together information about the operation, and that information is later used to evaluate the operation at run time. As part of the process, variables of type dynamic are compiled into variables of type object. Therefore, type dynamic exists only at compile time, not at run time.
(emphasis mine)
Since a dynamic reference needs to be able to take any type, it is in effect of the type object (or at least to all appearances and uses), but the compiler will not perform certain type checks on it.
Related
ECMA-CIL allows generic instances to actually yield a different implementation of the generic definition when instantiated. The instantiation can be specialized based on the chosen generic arguments.
Is there any case where a generic may behave differently if instantiated by a struct instead of an object reference? This is a question regarding semantics; I am not talking about performance.
In other words, could a naive implementation of ECMA-CIL decide to implement struct-instantiated generics as boxed values (as in Java)?
I read ECMA-CIL, but I'm still not sure about this. Any feedback is more than appreciated. Although I'm particularly interested in what happens at the bytecode level, an answer from the C# language perspective is also valuable.
Here's a simulated boxed value type in C#:
public class Boxed<T> where T : struct
{
public T Value; // do not assign to!
public Boxed(T value) => Value = value;
}
This is the best we can do at .NET level, since there is no native way to make a boxed value type reference (C++/CLI uses a tagged object to specify that). This is also more or less equivalent to System.Runtime.CompilerServices.StrongBox<T>.
Is there any case where a generic may behave differently if instantiated by a struct instead of an object reference? This is a question regarding semantics; I am not talking about performance.
Of course, using Boxed<T> means that default(Boxed<T>) is null for example. Here is a situation where this could be an issue:
public static class GlobalVariable<T>
{
public T Value;
}
If .NET actually implemented GlobalVariable<int> using GlobalVariable<Boxed<int>>, the Value field would contain null instead of 0. A conforming CLI implementation would have to implicitly use Value = new Boxed<T>(default(T)); when the type is instantiated, or modify ldfld (or ldflda) to create such an instance there if there is null (wreaking havoc for threading and readonly).
Another issue is copy semantics of value types. Each opcode like ldloc or similar assumes that a value type would be copied and mutating the value of the target should not affect the source. For example:
public static class GlobalVariable<T>
{
public T Value;
public delegate void Mutator(ref T value);
public static T MutateCopy(Mutator mutator)
{
var copy = Value;
mutator(ref copy);
return copy;
}
}
Calling something like GlobalVariable<Boxed<ValueTuple<int>>>.MutateCopy would pose an issue (if the runtime actually translated mutator(ref copy) to something like mutator(ref copy.Value) in order to call the delegate) since it would access the same instance. The runtime would have to "clone" Value as an object during the assignment in order to fix it.
Summed up, a value type type argument *could* be implemented using boxing, but without any additional special treatment, you get the same issues you would get in Java when using wrapper classes. It could work without mutable value types or strict null conversion checks (and potentially without byref parameters), but anything more than that will require additional (and complicated) changes to the implementation or languages. For an example of such a thing, see "unboxed" reference types in C++/CLI (i.e. reference types without the hat ^, which have value semantics).
While going through the ASP.NET MVC docs I see this idiom being used alot:
new { foo = "bar", baz = "foo" }
Is this a Dictionary literal syntax?
Is it a new class/struct with the type inferred by the called function definition?
If it is how come the vars don't need a type definition, not even var?
This is an anonymous type.
Anonymous types provide a convenient way to encapsulate a set of
read-only properties into a single object without having to explicitly
define a type first. The type name is generated by the compiler and is
not available at the source code level. The type of each property is
inferred by the compiler.
http://msdn.microsoft.com/en-us/library/bb397696.aspx
Anonymous types are strongly typed. From the perspective of the common language runtime, an anonymous type is no different from any other reference type.
If two or more anonymous types in the same assembly have the same number and type of properties, in the same order, the compiler treats them as the same type. They share the same compiler-generated type information.
Anonymous types should not be passed between assemblies or even as return values from methods (possible, but rarely, rarely advisable).
Anonymous types are a convenience mechanism, e.g. when working with LINQ, such as the following projection:
LINQ Example
var result = myEnumerable.Select( o => new { foo = o.Foo, bar = o.Bar } );
// "result" is an enumerable of a new anonymous type containing two properties
Other Questions
Is this a Dictionary literal syntax?
No, though there are many similarities. ASP .Net MVC uses RouteValueDictionary and anonymous types to represent the same information in many method overloads.
how come the vars don't need a type definition, not even var?
Value types are inferred, though inference is not always possible: http://msdn.microsoft.com/en-us/library/bb531357.aspx (VB version, if someone knows the URL of the c# equivalent please update)
This is an anonymous type syntax. The type name is generated by the compiler and is not available at the source code level. The type of each property is inferred by the compiler.
This is anonymous type. That means it is returning something which has a foo property, a baz property both of string type.
I have a class that contains a variable of indeterminate type, which must be overridden at runtime, how can I do this?
Sorry for the disgusting question(
Example:
public class MyClass
{
public e_Type TypeValue;
public (variable of indeterminate type) Value;
}
public enum e_Type
{
string, int, bool, byte
}
At runtime variable TypeValue should determine the type of variable Value
Depending on what you actually mean, you should use either var or dynamic.
The var keyword simply lets the compiler take care of deciding which type you are actually using. If the data you will be assigning is truly dynamic during runtime, it won't do you much good. You should mostly look at var as syntactic sugar (even if it at times can be very, very helpful sugar) - i.e. it just saves you typing.
The dynamic keyword lets you create an object that is truly dynamic, that is you will not get a compiler or runtime error no matter what you try to assign to it. The runtime errors will happen later down the road when you try to call on a property that doesn't exist on it. This is essentially you telling the compiler "Hey, look, just don't give me any fuss about this object, allow me to assign anything to it and call anything on it. If I mess up, it's my problem, not yours."
I think whenever you are thinking about using dynamic you should consider the problem at hand and see if it can be solved in a better way (interfaces, generics etc).
It sounds like you're really after generics:
class Foo<T>
{
public T Value { get; set; };
}
Then you can create instances for different types:
Foo<string> x = new Foo<string>();
x.Value = "fred";
Foo<int> y = new Foo<int>();
y.Value = 10;
This is still fixing the type at compile-time - but when the code using the type is compiled.
var is completely wrong here - var is just used for implicitly typed local variables. In particular, you can't apply it to fields.
It's possible that you want dynamic, but it's not really clear from your question at the moment.
I know that this must be done using the keyword var
Nope, that isn't what var does. There are 3 things that leap to mind that would work:
object; can store anything, but requires reflection to do anything useful
dynamic; a special-case of object, where the compiler performs voodoo such that obj.SomeMethod() (etc) is resolved at runtime
generics, i.e. have the class be SomeType<T>, with the variable typed as T; generic constraints can make this T more usable by declaring features (interfaces) that it must have
var has the purpose of referencing anything, not to declare anything. It's the other way around.
I acomplished this once leveraging the System.Dynamic.ExpandoObject (C# 4 only!), it allows for properties to be added at will without declaring them, and they will be resolved at runtime (it resembles how PHP treats objects and I'm a huge fan of it).
A quick example:
dynamic myObject = new ExpandoObject();
myObject.myProperty = "You can declare properties on-the-fly inside me !";
Console.WriteLine(myObject.myProperty);
I need to create a heterogeneous List of objects (custom classes). My first thought was to create a List<ISomeMarkerInterface> but I quickly learned that this is not what I want. My next thought was List<dynamic> and this didn't seem to be a bad idea. However, I was doing some research and came across this article about boxing and unboxing and in the example, they're doing basically what I want using List<Object>.
Aside from the fact that dynamic will be evaluated at runtime and Object at compile-time, what is the difference between List<dynamic> and List<Object>? Aren't they essentially the same thing?
There are 3 "general" types (although not all are real types) in C#: object, var and dynamic.
Object
An actual type, like any other type, with one special rule: if a type doesn't inherit, it inherits from object. From this, it follows that all types inherit from object, directly or indirectly.
Emphasis: object is a type. An object can be of type object, and the type has its methods, like ToString(). Since everything inherits from object, everything can be upcast into object. When you assign an object to an object reference, you are doing upcasting just like when you assign an Elephant type object to an Animal reference where Elephant inherits from Animal.
SomeType x = new SomeType();
object obj = x;
obj.DoSomething();
obj is treated as being of type object at compile time, and will be of type object at runtime (which is logical, since it is an actual type - obj is declared as object so can only be of that type)
obj.DoSomething() will cause a compile-time error, as object does not have this method, regardless of whether SomeType has it.
Var
This is not an actual type, it is merely shorthand for "compiler, figure out the type for me based on the right side of the assignment".
SomeType x = new SomeType();
var obj = x;
obj.DoSomething();
obj is treated as being of type SomeType at compile time, and will be of type SomeType at runtime, just as if you had written "SomeType" instead of "var".
if SomeType has a method DoSomething(), this code will work
if SomeType doesn't have the method, the code will cause a compile-time error
Dynamic
This is a type that tells the compiler to disable compile-time type checking on the variable. An object is treated as having the type dynamic at compile-time and run-time.
SomeType x = new SomeType();
dynamic obj = x;
obj.DoSomething();
obj is of type dynamic at compile and run time
if SomeType has a method DoSomething(), this code will work
if SomeType doesn't have the method, the code will compile, but throw an exception at run-time
note that dynamic can cause exceptions very easily if used carelessly:
public void f(dynamic x)
{
x.DoSomething();
}
This will throw an exception if x is of a type that doesn't have the DoSomething method, but it will still be possible to call it and pass any object as the parameter without a compile-time error, causing an error that only shows itself at run-time, and possibly only in specific circumstances - a potential bug. So if you use dynamic in any kind of public interface of a class, you should always manually type-check at runtime using reflection, carefully deal with exceptions, or not do it in the first place.
Note: the object being referred to never changes its type, of course. While obj may be object, the x that it refers to is still SomeType.
The difference is that if you use object and you try to access some member of your object it will be a compile time error (because object doesn't have this member). In order to work you need to know what the type is and cast it.
With dynamic you can access any member - no compile time error. If the member doesn't exist at runtime it would be a runtime error. This is the way to go if you know that your heretogeneous objects all have the same member for example.
However if this is the case there is another more clear solution: You can define an interface, with this member and then make all your heretogeneous objects implement it and your list can be List<IYourInterface>.
Keep in mind that dynamic's performance might be slightly worse, because of the, well, dynamic type resolution.
Is it possible to determine what type a dynamic member access expects? I've tried
dynamic foo = new MyDynamicObject();
int x = foo.IntValue;
int y = (int)foo.IntValue;
And in the TryGetMember intercept GetMemberBinder.ReturnType is object either way. I also implemented TryConvert wondering if it might get invoked to do the conversion, but it never is hit.
Is there some other override I'm missing that lets me determine what Type the caller wants so that I can do the appropriate conversion?
In C#, when using dynamic, the compiler always sets the binder to return type of object, and then does a second dynamic implicit conversion to the expected return type. So on a DynamicObject when called from c#, GetMemberBinder.ReturnType will always be object, but that said if you return another sort of springboard dynamic object with TryConvert implemented you could get that type, except if the user does var or dynamic as the variable, then they have a proxy that won't do anything until it becomes statically typed.
ImpromptuInterface does something different but along these lines, because it also has the desire to have a dynamic implementation that changes based on return types -- just you would have to describe the dynamic object via an interface.