So I started with no knowledge on reflection or dynamic typing, but I've learned a lot. However, there is one thing I cannot find: the "as" equivalent for dynamic typing.
What I'm trying to do is the equivalent of this (if it would compile):
foreach (Change c in changes)
{
(c.Undo as Action<c._Type, c._Type>).Invoke(
c.OldValue as c._Type, c.NewValue as c._Type);
}
From what I understand, I need to do something along the lines of
Type constructedClass = typeof(Action<,>).MakeGenericType(c._Type);
to construct the needed Action class, but is there a way to implement as for both the Action type and c._Type?
For further clarification, here is the pseudocode (and this is my first time trying to do this kind of thing, so please be nice):
foreach (Object o in objects)
{
(o.SettableMethod as Action<o.TypeOfParameters, o.TypeOfParameters>).Invoke(
o.Parameter1 as TypeOfParameters, o.Parameter2 as TypeOfParameters);
}
Thanks in advance.
The purpose of the generics on the Action (or in general) is to allow you to manage type safety at compile time. If you use reflection, you are doing extra work to not get that benefit. You might as well have the signature of your Undo Action take two objects of type object, and cast to appropriate types inside the action, if needed.
Even more generally, you would be better served by a different design. Why are you calling a method on Change that sends properties of Change back in? Could you not call Undo without any parameters, and leave Change responsible for knowing what the new and old values are?
Related
Intro
To create instances on the fly via reflection, we could use:
Activator.CreateInstance
The downside to this is that this returns an object, while I really need the concrete type and since I only know the runtime type I can't cast.
To accomplish this, we can use
Activator.CreateInstance<T>
Which returns a T, but since I don't know T at compile time, this is no use either. At first glance anyway.
Currently I'm using dynamic for this, in a special kind of way:
//I pass the runTimeType as an ITopSecret
// runTimeType implements ITopSecret
dynamic concreteTypeInstance = Activator.CreateInstance(runTimeType);
// Now we just have an empty RunTimeType.
// I can use the passed runTimeType to fill the newly created object
concreteTypeInstance = runTimeType
// Then I call ApplyCurrentValues.
// Can't pass runTimeType, because it's ITopSecret and
// EF doesn't figure out the actual runtime type.
context.ApplyCurrentValues(concreteTypeInstance)
Before this line some sanity checks are performed. For example I know the runtime type is always a certain ITopSecret at this point, otherwise the statement can't get hit.
So presumably this is reasonably safe. It does exactly what I want, with 1 line of code, which seems great.
However I'm not sure this is the intended way of using dynamic and if I'm setting the door open for nasty stuff.
Why do I want this
Currently we have 1000s of lines of boilerplate code in many Update methodes across various services. This is handcrafted, thus error-prone, repetetive, violates DRY and makes it harder for new people.
Furthermore this makes the methods unclear by losing focus on business logic and, frankly, is just plain ugly. All the usual suspects ;)
So I'm writing some abstract/generic code to factor out all that repetitive stuff. Which is a very nice and cool bit of software to write, but leaves me with (mostly) runtime info.
Under the surface these methods all use Entity Framework and its ApplyCurrentValues method. This method requires a concrete, instantianted, type and hence my questions.
Hope this is clear enough :)
Questions
Is this an OK way to use dynamic, considering I perform do some sanity checks before actually using it?
I feel that there's a way using reflection to accomplish this. That might be worse in terms of performance, but I'm very curious if this can be done.
Is it possible to create the generic Activator.CreateInstance<T> using reflection?
Are either possibilities bad and should I take a different approach entirely?
However not knowing the concrete types at run-time, but needing them anyway is not something I can move away from.
Is there any way, without using Reflection, of writing something along the lines of OSteele's Functional Invoke in C#?
This means using it as in:
Action<T> MethodName = StaticUtil.Invoke<T>("MethodName", optionalCurriedArgs);
And then calling:
MethodName(objWithMethodName);
I know using a Lambda would do the trick.
What I mean, is using something along the lines of AS3's:
public static function invoke( selectedMethod : String, ... arguments ) : Function {
var args : Array = arguments.slice();
return function ( object : * ) : * {
return object[ selectedMethod ].apply( object, args);
};
}
Thank you for reading.
No. There is no obvious way in C# without using Reflection to call a function on a particular class. At best you might try dynamic and let it be resolved at runtime. You can try using a library like FasterFlect to solve your need.
Alternatively, if you want a built in method you can do
typeof(MyObject).InvokeMember(methodName
,BindingFlags.Public | BindingFlags.Instance
,null
,myInstance
,new object[]{parameter1,parameter2})
I would be lying to you if I said it wasn't reflection though. The CLR wasn't designed for you to invoke methods dynamically like javascript. This was a conscious decision to make a high performance method call. If you need to pass functions around use Delegates. If your method needs variable argument support you can use overloads, or params. If you need to call methods dynamically via strings:
use Dictionary<string,DelegateType> or if you know you have a few methods and need absolute speed use a List<Tuple<string,DelegateType>>. If you have many types that all respond to a message use Interfaces. If the classes aren't your own, or they are specialized for primitives try dynamic.
C# is a well designed language written for standard coding practices. There are lots of options. If you really need to they give you the tools to look up members and invoke them. Reflection is slow because the CLR was designed to be SAFE first. If you find yourself needing lots of reflection dynamic invocation you might want to reconsider your design choices. If you still can find no other way you can still use caching and Delegates to make that fast. dynamic is entirely done with clever caching and delegates, and dynamic in the best cases is nearly as fast as native code.
In theory, you can create a pattern like CallSite<T> in the DLR to fast cache a particular call site. I do something similar in a dynamic proxy I wrote to get around the fact that there is no way to create a function pointer to an open generic method. (e.g. I wanted to have a mydelegate.Invoke<T>(T arg) ).
I would imagine this might use Reflection.Emit,
but a similar question on SO only answers how to create a class/method dynamically, not how to update an existing class.
In a similar vein, is it possible to delete methods / classes at runtime? If so, I suppose one could just delete the class, and add it back with its old methods plus the new one.
Thanks in advance.
P.S. I don't have an intended use for this, it is merely a matter of curiosity.
In regular C# / .NET, the answer is a simple "no". The most you can do is write a DynamicMethod which can behave like a method of that type (access to private fields etc), but it won't ever be on the API - you just end up with a delegate.
If you use dynamic, you can do pretty much anything you want. You can emulate that with ExpandoObject by attaching delegates in place of methods, but on a custom dynamic type you can do most anything - but this only impacts callers who use the dynamic API. For a basic ExpandoObject example:
dynamic obj = new ExpandoObject();
Func<int, int> func = x => 2*x;
obj.Foo = func;
int i = obj.Foo(123); // now you see it
obj.Foo = null; // now you don't
For properties and events (not methods), you can use the System.ComponentModel approach to change what appears at runtime, but that only impacts callers who get access via System.ComponentModel, which means mainly: UI data-binding. This is how DataTable represents columns as pseudo-properties (forgetting about "typed datasets" for the moment - it works without those).
For completeness, I should also mention extension methods. Those are more a compiler trick, not a runtime trick - but kinda allow you to add methods to an existing type - for small values of "add".
One final trick, commonly used by ORMs etc - is to dynamically subclass the type, and provide additional functionality in the subclass. For example, overriding properties to intercept them (lazy-loading, etc).
is it possible to delete methods / classes at runtime?
Suppose that it was possible. Calls to those methods would fail and produce undefined (but usually catastrophic) behaviour.
So I'm sure it is not possible.
I never seem to understand why we need delegates?
I know they are immutable reference types that hold reference of a method but why can't we just call the method directly, instead of calling it via a delegate?
Thanks
Simple answer: the code needing to perform the action doesn't know the method to call when it's written. You can only call the method directly if you know at compile-time which method to call, right? So if you want to abstract out the idea of "perform action X at the appropriate time" you need some representation of the action, so that the method calling the action doesn't need to know the exact implementation ahead of time.
For example:
Enumerable.Select in LINQ can't know the projection you want to use unless you tell it
The author of Button didn't know what you want the action to be when the user clicks on it
If a new Thread only ever did one thing, it would be pretty boring...
It may help you to think of delegates as being like single-method interfaces, but with a lot of language syntax to make them easy to use, and funky support for asynchronous execution and multicasting.
Of course you can call method directly on the object but consider following scenarios:
You want to call series of method by using single delegate without writing lot of method calls.
You want to implement event based system elegantly.
You want to call two methods same in signature but reside in different classes.
You want to pass method as a parameter.
You don't want to write lot of polymorphic code like in LINQ , you can provide lot of implementation to the Select method.
Because you may not have the method written yet, or you have designed your class in such a way that a user of it can decide what method (that user wrote) the user wants your class to execute.
They also make certain designs cleaner (for example, instead of a switch statement where you call different methods, you call the delegate passed in) and easier to understand and allow for extending your code without changing it (think OCP).
Delegates are also the basis of the eventing system - writing and registering event handlers without delegates would be much harder than it is with them.
See the different Action and Func delegates in Linq - it would hardly be as useful without them.
Having said that, no one forces you to use delegates.
Delegates supports Events
Delegates give your program a way to execute methods without having to know precisely what those methods are at compile time
Anything that can be done with delegates can be done without them, but delegates provide a much cleaner way of doing them. If one didn't have delegates, one would have to define an interface or abstract base class for every possible function signature containing a function Invoke(appropriate parameters), and define a class for each function which was to be callable by pseudo-delegates. That class would inherit the appropriate interface for the function's signature, would contain a reference to the class containing the function it was supposed to represent, and a method implementing Invoke(appropriate parameters) which would call the appropriate function in the class to which it holds a reference. If class Foo has two methods Foo1 and Foo2, both taking a single parameter, both of which can be called by pseudo-delegates, there would be two extra classes created, one for each method.
Without compiler support for this technique, the source code would have to be pretty heinous. If the compiler could auto-generate the proper nested classes, though, things could be pretty clean. Dispatch speed for pseudo-delegates would probably generally be slower than with conventional delegates, but if pseudo-delegates were an interface rather than an abstract base class, a class which only needs to make a pseudo-delegate for one method of a given signature could implement the appropriate pseudo-delegate interface itself; the class instance could then be passed to any code expecting a pseudo-delegate of that signature, avoiding any need to create an extra object. Further, while the number of classes one would need when using pseudo-delegates would be greater than when using "real" delegates, each pseudo-delegate would only need to hold a single object instance.
Think of C/C++ function pointers, and how you treat javascript event-handling functions as "data" and pass them around. In Delphi language also there is procedural type.
Behind the scenes, C# delegate and lambda expressions, and all those things are essentially the same idea: code as data. And this constitutes the very basis for functional programming.
You asked for an example of why you would pass a function as a parameter, I have a perfect one and thought it might help you understand, it is pretty academic but shows a use. Say you have a ListResults() method and getFromCache() method. Rather then have lots of checks if the cache is null etc. you can just pass any method to getCache and then only invoke it if the cache is empty inside the getFromCache method:
_cacher.GetFromCache(delegate { return ListResults(); }, "ListResults");
public IEnumerable<T> GetFromCache(MethodForCache item, string key, int minutesToCache = 5)
{
var cache = _cacheProvider.GetCachedItem(key);
//you could even have a UseCache bool here for central control
if (cache == null)
{
//you could put timings, logging etc. here instead of all over your code
cache = item.Invoke();
_cacheProvider.AddCachedItem(cache, key, minutesToCache);
}
return cache;
}
You can think of them as a construct similar with pointers to functions in C/C++. But they are more than that in C#. Details.
I'm very excited about the dynamic features in C# (C#4 dynamic keyword - why not?), especially because in certain Library parts of my code I use a lot of reflection.
My question is twofold:
1. does "dynamic" replace Generics, as in the case below?
Generics method:
public static void Do_Something_If_Object_Not_Null<SomeType>(SomeType ObjToTest) {
//test object is not null, regardless of its Type
if (!EqualityComparer<SomeType>.Default.Equals(ObjToTest, default(SomeType))) {
//do something
}
}
dynamic method(??):
public static void Do_Something_If_Object_Not_Null(dynamic ObjToTest) {
//test object is not null, regardless of its Type?? but how?
if (ObjToTest != null) {
//do something
}
}
2. does "dynamic" now allow for methods to return Anonymous types, as in the case below?:
public static List<dynamic> ReturnAnonymousType() {
return MyDataContext.SomeEntities.Entity.Select(e => e.Property1, e.Property2).ToList();
}
cool, cheers
EDIT:
Having thought through my question a little more, and in light of the answers, I see I completely messed up the main generic/dynamic question. They are indeed completely different. So yeah, thanks for all the info.
What about point 2 though?
dynamic might simplify a limited number of reflection scenarios (where you know the member-name up front, but there is no interface) - in particular, it might help with generic operators (although other answers exist) - but other than the generic operators trick, there is little crossover with generics.
Generics allow you to know (at compile time) about the type you are working with - conversely, dynamic doesn't care about the type.
In particular - generics allow you to specify and prove a number of conditions about a type - i.e. it might implement some interface, or have a public parameterless constructor. dynamic doesn't help with either: it doesn't support interfaces, and worse than simply not caring about interfaces, it means that we can't even see explicit interface implementations with dynamic.
Additionally, dynamic is really a special case of object, so boxing comes into play, but with a vengence.
In reality, you should limit your use of dynamic to a few cases:
COM interop
DLR interop
maybe some light duck typing
maybe some generic operators
For all other cases, generics and regular C# are the way to go.
To answer your question. No.
Generics gives you "algorithm reuse" - you write code independent of a data Type. the dynamic keyword doesn't do anything related to this. I define List<T> and then i can use it for List of strings, ints, etc...
Type safety: The whole compile time checking debate. Dynamic variables will not alert you with compile time warnings/errors in case you make a mistake they will just blow up at runtime if the method you attempt to invoke is missing. Static vs Dynamic typing debate
Performance : Generics improves the performance for algorithms/code using Value types by a significant order of magnitude. It prevents the whole boxing-unboxing cycle that cost us pre-Generics. Dynamic doesn't do anything for this too.
What the dynamic keyword would give you is
simpler code (when you are interoperating with Excel lets say..) You don't need to specify the name of the classes or the object model. If you invoke the right methods, the runtime will take care of invoking that method if it exists in the object at that time. The compiler lets you get away even if the method is not defined. However it implies that this will be slower than making a compiler-verified/static-typed method call since the CLR would have to perform checks before making a dynamic var field/method invoke.
The dynamic variable can hold different types of objects at different points of time - You're not bound to a specific family or type of objects.
To answer your first question, generics are resolved compile time, dynamic types at runtime. So there is a definite difference in type safety and speed.
Dynamic classes and Generics are completely different concepts. With generics you define types at compile time. They don't change, they are not dynamic. You just put a "placeholder" to some class or method to make the calling code define the type.
Dynamic methods are defined at runtime. You don't have compile-time type safety there. The dynamic class is similar as if you have object references and call methods by its string names using reflection.
Answer to the second question: You can return anonymous types in C# 3.0. Cast the type to object, return it and use reflection to access it's members. The dynamic keyword is just syntactic sugar for that.