How to construct a call to a method using dynamic - c#

Hi I have a namespace with a lot of classes and all of them has a method Destroy(int id)
I want to call that method using dynamic word.
Here is my example:
public bool DeleteElement<T>(T tElement)
{
Type t = typeof(T);
dynamic element = tElement;
var id = element.Id;
//until here everything is fine
//here I want to say
(namespace).myClassName.Destroy(id);
//the name of myClassName is like t.ToString()
}
I can avoid namespace including a using at the top. The idea is to call that static method using dynamic, not Reflection, please see that Destroy is a static method of T. I need something like this T.Destroy(id)

If Destroy(int id) is a static method, couldn't you create an instance method that would call the static one?
public void Destroy()
{
ThisClass.Destroy(this.Id);
}
You could then define an IDestroyable interface implemented by all these classes:
interface IDestroyable { void Destroy(); }
And then modify your DeleteElement method as follows:
public bool DeleteElement<T>(T tElement) where T : IDestroyable
{
tElement.Destroy();
}
No need to use dynamic here... Actually, using dynamic in this situation is often an indication of bad design. It's quite rare to actually need dynamic except in the scenarios for which it was created (e.g. interop with dynamic languages)
(If the classes are generated but they have the partial modifier, you can declare the new method in another file that is not touched by the generator)
EDIT: if the classes are generated and are not partial, you can't modify them... So another solution would be to use reflection; I know you want to avoid that (for performance reasons I assume), but you can limit the performance impact by doing the reflection only once for each type: you just need to create and cache a delegate for each type.
class DestroyHelper<T>
{
static readonly Action<int> _destroy;
static readonly Func<T, int> _getId;
static DestroyHelper()
{
var destroyMethod = typeof(T).GetMethod("Destroy", BindingFlags.Static | BindingFlags.Public);
_destroy = (Action<int>)Delegate.CreateDelegate(typeof(Action<int>), destroyMethod);
var getIdMethod = typeof(T).GetProperty("Id").GetGetMethod();
_getId = (Func<T, int>)Delegate.CreateDelegate(typeof(Func<T, int>), getIdMethod);
}
public static void Destroy(T element)
{
_destroy(_getId(element));
}
}

Related

Provide extension method for types derived from `this` type

I've read this similar question I don't expect the same behavior as the OP and I don't really understand him but I have a usage for protected members inside the derived classes.
In Why is the 'this' keyword required to call an extension method from within the extended class Eric Lippert wrote:
... If you are in the scenario where you are using an extension method
for a type within that type then you do have access to the source
code. Why are you using an extension method in the first place then?
... Given those two points, the burden no longer falls on the language
designer to explain why the feature does not exist. It now falls on
you to explain why it should. Features have enormous costs associated
with them.
...
So I will try to explain why I would expect a behavior and it's usage example.
The feature:
A programer can access protected member of this object inside extension method.
When a protected member is used within extension method, you can only use the method inside classes derived from type of this object.
Protected extension method can be called only with this argument object which is the same object that is accessible by this keyword in caller method.
Real life usage scenario:
I'm playing with creating a Visual Studio custom editor based on WPFDesigner_XML example.
Currently I'm trying to figure things out in class with following signature:
public sealed class EditorPane : WindowPane, IOleComponent, IVsDeferredDocView, IVsLinkedUndoClient
{...}
Lot of methods are using services Like this:
void RegisterIndependentView(bool subscribe)
{
IVsTextManager textManager = (IVsTextManager)GetService(typeof(SVsTextManager));
if (textManager != null)
{
if (subscribe)
{
textManager.RegisterIndependentView(this, _textBuffer);
}
else
{
textManager.UnregisterIndependentView(this, _textBuffer);
}
}
}
I like to keep focus on things that actually matter so I wrote helper method to simplify such methods. For example:
private void RegisterIndependentView(bool subscribe) {
if (with(out IVsTextManager tm)) return;
if (subscribe) tm.RegisterIndependentView(this, _textBuffer);
else tm.UnregisterIndependentView(this, _textBuffer);
}
The with method look like this:
private bool with<T>(out T si) {
si = (T)GetService(getServiceQueryType<T>());
return si == null ? true : false;
}
And I placed getServiceQueryType<T>() in a static class:
public static class VSServiceQueryHelper {
public static Type getServiceQueryType<T>() {
var t = typeof(T);
if (!serviceQueryTypesMap.ContainsKey(t)) throw new Exception($#"No query type was mapped in ""{nameof(serviceQueryTypesMap)}"" for the ""{t.FullName}"" interface.");
return serviceQueryTypesMap[t];
}
private static Dictionary<Type, Type> serviceQueryTypesMap = new Dictionary<Type, Type>() {
{ typeof(IVsUIShellOpenDocument), typeof(SVsUIShellOpenDocument) },
{ typeof(IVsWindowFrame), typeof(SVsWindowFrame) },
{ typeof(IVsResourceManager), typeof(SVsResourceManager) },
{ typeof(IVsRunningDocumentTable), typeof(SVsRunningDocumentTable) },
{ typeof(IMenuCommandService), typeof(IMenuCommandService) },
{ typeof(IVsTextManager), typeof(SVsTextManager) },
};
}
This works well but I would also like to place the with method inside VSServiceQueryHelper as an extension so any time I would extend WindowsPane i could just place using static com.audionysos.vsix.utils.VSServiceQueryHelper; at the top and use the with method that is already implemented.
The problem:
I can't make with method an extension because the GetService method used by it is a protected member of the WindowsPane which is the base type of my class. So now I need to place with implementation in every class that extends WindowPane and this breaks the rule of never repeat yourself :/
A simple solution would be to create a base class containing the With method.
If that is too burdensome, then you can also implement this using Reflection to invoke the GetService method from the extension method. In fact, we can create a delegate to it that will ensure there is minimal overhead to invoking With many times.
internal static class WindowPaneExtensions
{
private static readonly Func<WindowPane, Type, object> WindowPaneGetService = CreateWindowPaneGetService();
public static bool With<T>(this WindowPane pane, out T service)
{
service = (T)WindowPaneGetService(pane, GetServiceQueryType<T>());
return service != null;
}
private static Func<WindowPane, Type, object> CreateWindowPaneGetService()
{
var method = typeof(WindowPane).GetMethod("GetService", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(Type) }, null);
var del = (Func<WindowPane, Type, object>)method.CreateDelegate(typeof(Func<WindowPane, Type, object>));
return del;
}
}
I think your proposal to allow certain extension methods access to protected members is a non-starter. For example, the following is not allowed:
public class MyPane : WindowPane
{
public static void Test(WindowPane p)
{
var service = p.GetService(typeof(Service));
// etc.
}
}
But you ask, "Isn't it allowed to access base class members from a derived class?" No, that actually isn't the rule. The rule is that you can access base class members from derived class only via a reference to the derived class, not from any base class reference directly. More details on this here. Your proposal amounts to allowing this kind of thing for an even larger class methods (i.e. methods that some other library author declares to be extension methods). Eric Lippert has written about this issue (here and here) in the past as well. Since cross hierarchy calls are blocked by the CLR, I would not expect something like this proposal to get implemented any time soon.

Inheritance in c# using reflection

I am in a situation where i have to inherit a class and access its protected method to get a value.
Due to some weird situations i have most of my code in reflection and i m hoping if i have any chance to get this working using reflection.
To make things more clear,
Below is the class
public class Converter: BaseConverter
{
public Converter();
protected override object StringToValue();
}
I need to do below to get the functionality working.
public class myclass:Converter
{
public StringToValue()
{
base.StringToVaue();
}
}
However I cannot use direct reference of Converter dll in my project . So i am handicapped here to use inheritance and myclass : converter. So how can i approach this using reflection which would be to basically make myclass inherit the converter class at runtime. I am not sure if it makes sense or not however it seems to me that its where i am trying to head towards to get an answer
You can use TypeBuilder to create a whole new type at runtime via reflection. Of course ultimately you need a reference to the assembly which contains Converter to inherent from it. Make sure to check out the MSDN example of TypeBuidler. You need to call ModuleBuilder.DefineType() which has an overload to specify the parent type.
But if you go that way you have to do everything with reflection including emitting the methods. I don't fully understand your restrictions so that's the best answer I could think of but I don't really like it ;)
While we're talking about hacking: Do you really need to inherit from Converter or do you only need to access its methods? In case you only need the methods you could simply hold an instance of Converter as an attribute of type object and call the protected method via refletion inside your public StringToValue method.
EDIT:
As you ask for sample code. With reflection you can bypass the class security mechanism of C#, which means you're able to call non-public methods on any object. First you need the Type. Because you can't write it out in C# you need to get it some other way. Then you can create an instance of that type with Activator. You also need to obtain information about the method you want to call. It makes sense to cache this information because the processes of reading that information with reflection is kinda slow. Finally you can use the MethodInfo to actually call the method.
I haven't tested that code because I don't have a machine to do so right now.
class myclass
{
object internalConverter;
MethodInfo converterStringToValueMethod;
public myclass()
{
// Here you need a reference to the assembly which contains the Converter type
Assembly asm = Assembly.Load("xxx.dll"); // Name of the assembly which contains Converter
Type converterType = asm.GetType("Converter");
this.internalConverter = Activator.CreateInstance(converterType);
this.converterStringToValueMethod = converterType.GetMethod("StringToValue", BindingFlags.NonPublic | BindingFlags.Instance);
}
public object StringToValue()
{
return converterStringToValueMethod.Invoke(internalConverter, null);
}
}
This should do what you want without inheritance:
using System;
using System.Reflection;
namespace Test
{
class Converter
{
string Value;
public Converter(string test)
{
Value = test;
}
protected object StringToValue()
{
return Value;
}
}
class myclass
{
object Unknown;
public myclass(object other)
{
Unknown = other;
}
MethodInfo originalFunction;
public object StringToValue()
{
if (originalFunction == null)
{
originalFunction = Unknown.GetType().GetMethod("StringToValue", BindingFlags.NonPublic | BindingFlags.Instance);
}
return originalFunction.Invoke(Unknown, null);
}
}
class Test
{
[System.STAThread]
public static void Main(string[] args)
{
Converter unknown = new Converter("TEST");
myclass mine = new myclass(unknown);
Console.WriteLine(mine.StringToValue());
Console.ReadLine();
}
}
}
This is a bad idea for a number of reasons, but if you are sure it is what you need...

C# dynamic executing function by its name?

I have a dynamic variable
dynamic d = GetSomeObject();
Sometime , in future, a user send me a function to execute ( its name) e.g "UsersGetAll"
So I need to do something like : d.UsersGetAll()
I can do it with reflection. But I want to use the DLR .
Does the only solution of doing this is to have MyObject inherit from DynamicObject and then implement TryInvokeMember?
What if I don't have control over the class ?
As Jon notes, the following really only applies if you suspect that the type is providing the method at runtime via the DLR; in most simple cases, reflection will be easier.
dynamic is intended when you know the method name but not the target. If you don't know the method name it is tricker. The tricky bit, perhaps, is ensuring you keep the call-site so that it can be re-used (which is how the DLR maintains performance). One cheeky way would be a static utility class that keeps track of invoked methods. Here's an example - note that it gets much messier if you need to handle parameters:
using Microsoft.CSharp.RuntimeBinder;
using System;
using System.Collections;
using System.Runtime.CompilerServices;
public class Foo
{
public object Bar() { return "I was here"; }
}
static class Program
{
static void Main()
{
object obj = new Foo();
object result = DynamicCallWrapper.Invoke(obj, "Bar");
Console.WriteLine(result);
}
}
static class DynamicCallWrapper
{
// Hashtable has nice threading semantics
private static readonly Hashtable cache = new Hashtable();
public static object Invoke(object target, string methodName)
{
object found = cache[methodName];
if (found == null)
{
lock (cache)
{
found = cache[methodName];
if(found == null)
{
cache[methodName] = found = CreateCallSite(methodName);
}
}
}
var callsite = (CallSite<Func<CallSite, object,object>>)found;
return callsite.Target(callsite, target);
}
static object CreateCallSite(string methodName)
{
return CallSite<Func<CallSite, object, object>>.Create(
Binder.InvokeMember(
CSharpBinderFlags.None, methodName, null, typeof(object),
new CSharpArgumentInfo[] {
CSharpArgumentInfo.Create(
CSharpArgumentInfoFlags.None, null) }));
}
}
I can do it with reflection. But I want to use the DLR.
Why? Assuming this is a "normal" object which isn't actually going to respond dynamically, reflection is going to be the easiest approach here.
The dynamic feature in C# 4 (in terms of the language feature) does absolutely nothing to help you here. It only allows dynamic binding of member names within C# source code.
Now you could:
Start an IronPython session, and create a tiny Python script to call the method using dynamic binding.
Use CSharpCodeProvider to compile some C# code using dynamic with the relevant method name, then execute that code.
Look at the generated code for your d.UsersGetAll() call, and basically emulate that.
All of these options are likely to be harder than reflection, if all you want it so call a "normal" method on a "normal" object, and you happen to only know the name at execution time.

Why does dynamic type work where casting does not?

My guess until now was that a dynamic type just "switches off" type checking during compilation and does something similar to a type cast when a message is invoked on a dynamic instance. Obviously something else is going on.
The attached NUnit test case shows my problem: Using a dynamic type I can use a method only available in the concrete subclass, but I cannot do the same using a cast (results in InvalidCastException). I'd rather do the casting since this gives me full code completion in VS.
Can anyone explain what's happening and/or give me a hint how I could get code completion in my case without having to reimplement the WorkWithAndCreate-method in every concrete subclass?
cheers, Johannes
using System;
using NUnit.Framework;
namespace SlidesCode.TestDataBuilder
{
[TestFixture]
public class MyTest
{
[Test]
public void DynamicWorks()
{
string aString = CreateDynamic(obj => obj.OnlyInConcreteClass());
Assert.AreEqual("a string", aString);
}
private static string CreateDynamic(Action<dynamic> action)
{
return new MyConcreteClass().WorkWithAndCreate(action);
}
[Test]
public void CastingDoesNotWorkButThrowsInvalidCastException()
{
string aString = CreateWithCast(obj => obj.OnlyInConcreteClass());
Assert.AreEqual("a string", aString);
}
private static string CreateWithCast(Action<MyConcreteClass> action)
{
return new MyConcreteClass().WorkWithAndCreate((Action<MyGenericClass<string>>) action);
}
}
internal abstract class MyGenericClass<T>
{
public abstract T Create();
public T WorkWithAndCreate(Action<MyGenericClass<T>> action)
{
action(this);
return this.Create();
}
}
internal class MyConcreteClass : MyGenericClass<string>
{
public override string Create()
{
return "a string";
}
public void OnlyInConcreteClass()
{
}
}
}
Here's the formatted real world example from my comment:
Customer customer = ACustomer(cust =>
{
cust.With(new Id(54321));
cust.With(AnAddress(addr => addr.WithZipCode(22222)));
});
private static Address AnAddress(Action<AddressBuilder> buildingAction)
{
return new AddressBuilder().BuildFrom(buildingAction);
}
private static Customer ACustomer(Action<CustomerBuilder> buildingAction)
{
return new CustomerBuilder().BuildFrom(buildingAction);
}
Some details are missing from it but I hope it makes the purpose clear.
The reason dynamic works is that dynamic does not depend on compile time knowledge of the object types. MyGenericClass<string> does not have the method OnlyInConcreteClass(), but the instance you are passing of course does have the method and dynamic finds this.
By the way, you can make WorkWithAndCreate work like this:
public T WorkWithAndCreate<T1>(Action<T1> action)
where T1 : MyGenericClass<T>
{
action((T1)this);
return this.Create();
}
Then, the call will work too:
private static string CreateWithCast(Action<MyConcreteClass> action)
{
return new MyConcreteClass().WorkWithAndCreate(action);
}
You now don't have to cast it anymore.
And concerning your builder, would the following work?
private static TResult AnInstance<TBuilder, TResult>(Action<TBuilder> buildingAction)
where TBuilder : Builder<TResult>, new()
{
return new TBuilder().BuildFrom(buildingAction);
}
This is an example of how to use dynamic:
http://msdn.microsoft.com/en-us/library/dd264736.aspx
You said:
My guess until now was that a dynamic type just "switches off" type checking during compilation and does something similar to a type cast when a message is invoked on a dynamic instance
Actually, it uses reflections to look up the methods, properties, and fields you invoke by name, at runtime. No casting is done, unless you actually cast the object back to its underlying type.
As for your actual problem, can you give a more concrete example? There may be a better design, but you haven't told us what you're trying to do - just what you're currently doing.
Hazarding a guess, you may want to use a base interface, and make all your functions accept that base interface. Then put the methods you want to call on that interface, and implement them in your concrete types. Usually dynamic is used as a work around when you don't have a base type, or can't modify the base type to add virtual or abstract methods.
If you really want to get this working, as-is, you must write it with a generic type parameter, not a dynamic type parameter. See Pieter's solution for how to do this properly.

Controlling when the Static Constructor is called

In my custom attribute's static constructor, I search the loaded assembly for all classes decorated with my attribute and perform some action on them.
I would like the static constructor to be called as soon as possible during runtime, preferably before execution of the static void Main() entry point.
Currently it only gets called after I make some call to the attribute. I could make such a call elsewhere in my program, but ideally the attribute's functionality would be self-contained.
Looking for answers, I read this on MSDN:
The user has no control on when the static constructor is executed in the program.
But surely there is some tricky, sly, or mischievous workaround to get a static constructor to be called ASAP. Perhaps an attribute, reflection, or some other kind of magic could be used. Can it be done?
Because people would undoubtedly tell me that there is no good reason to do what I ask, I present my purpose and my code: I am trying to use attributes to declaratively configure a db4o factory. If my attribute's static constructor is called after I've already established a connection, then it has no effect and is useless. Therefore it must be called before my program gets a chance to establish such a connection.
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
sealed public class CascadeOnUpdateAttribute : Attribute
{
public bool Flag { get; private set; }
public CascadeOnUpdateAttribute() : this(true) { }
public CascadeOnUpdateAttribute(bool flag)
{
Flag = flag;
}
static CascadeOnUpdateAttribute()
{
var targets = from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
from attribute in type.GetCustomAttributes(typeof(CascadeOnUpdateAttribute), false).Cast<CascadeOnUpdateAttribute>()
select new { Type = type, Cascade = attribute.Flag };
foreach (var target in targets)
{
Db4oFactory.Configure().ObjectClass(target.Type).CascadeOnUpdate(target.Cascade);
}
}
}
Update:
I ended up using an abstract attribute with a static method. This way I can derive as many attributes as I like and they will all be applied to a specified config by calling this one method.
public abstract class Db4oAttribute : Attribute
{
public abstract void Configure(IConfiguration config, Type type);
public static void ApplyAttributes(IConfiguration config)
{
var targets = from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
from attribute in type.GetCustomAttributes(typeof(Db4oAttribute), false).Cast<Db4oAttribute>()
select new { Type = type, Attribute = attribute };
foreach (var target in targets)
{
target.Attribute.Configure(config, target.Type);
}
}
}
And the call site:
Db4oAttribute.ApplyAttributes(Db4oFactory.Configure());
_db = Db4oFactory.OpenFile("Test.db4o");
As Marc says, I would do it explicitly in Main if I were you.
You can invoke the type initializer for a type explicitly using the Type.TypeInitializer property and invoking it. However, this will cause it to run again even if it's already been run which could produce unexpected results.
I would personally move that code out of the static initializer completely. It's configuration code - why not just make it a static method which you can call explicitly? I'm not even sure I'd have it in the attribute class itself, but at least explicitly calling:
CascadeOnUpdateAttribute.ConfigureDb4oFactories();
is clearer than calling a dummy method or forcing type initialization some other way, just to get a side effect.
If you want the static constructor to get called, then add a dummy method to the type and simply call it at the start of your code (Main etc); if it is a trivial / empty method you might want to mark it for no inlining etc.
class SomeType {
static SomeType() {
Console.WriteLine("SomeType.cctor");
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static void Init() { }
}
static class Program {
static void Main() {
SomeType.Init();
Console.WriteLine("hi");
}
}
You can use reflection to call the static constructor, but I don't recommend it; if you use reflection you can actually call the .cctor multiple times, and that is never a good thing...
You can avoid the static dummy method by calling
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(CascadeOnUpdateAttribute).TypeHandle)
I think the use of the static constructor smells; I would consider refactoring your code to control access to the db4o factory so that you don't need to use it.

Categories

Resources