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...
Related
Consider following code:
public class Test
{
[System.AttributeUsage(System.AttributeTargets.Method)]
class MethodAttribute : System.Attribute
{
public MethodAttribute(System.Reflection.MethodInfo methodInfo)
{
}
}
public void Foo()
{
}
[Method(Test.Foo)] //< THIS IS THE IMPORTANT LINE
public void Boo()
{
}
}
I want to store MethodInfo instance of Foo in attribute of Boo, but problem is, that I cannot use Foo nor Test.Foo to get instance of MethodInfo. I can NOT use typeof(Test).GetMethod("Foo") (not my decision).
Important information:
Generated error is: error CS0120: An object reference is required to access non-static member `Test.Foo()'
I'm coding in Unity3D which is using Mono, not .Net. (more info http://docs.unity3d.com/410/Documentation/ScriptReference/MonoCompatibility.html )
Windows 7
Absolutely unimportant information:
Why I cannot use typeof(Test).GetMethod("Foo"): I'm not allowed. It's not in my power to change this decision. I can not. (Also, personally, I would like to avoid it anyway as it needs to do some lookup instead of getting statically the data. Also it won't be changed automatically during refactoring and will be checking run-time, not compile-time.)
Why I want to do this: later in code, I want to create a delegate of Boo() (this time normally, with an instance) and use in special even system or something. Before it's called, this attribute allows to setup method to be called in prepare for main event (it's optional, it can be null) and I know how to create a delegate when I have an object and a method info.
Why I cannot just provide both delegates when registering or something: because class containing these methods is not always the one who registers to event source, I need to keep the registration code as simple as possible. In other words, I want to avoid situation when person writing method responsible for connecting forgots to add this preparation delegate.
use expression :
static public class Metadata<T>
{
static public PropertyInfo Property<TProperty>(Expression<Func<T, TProperty>> property)
{
var expression = property.Body as MemberExpression;
return expression.Member as PropertyInfo;
}
}
var foo = Metadata<Test>.Property(test => test.Foo);
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.
public class BusinessObjects<O>
where O : BusinessObject
{
void SomeMethod()
{
var s = O.MyStaticMethod(); // <- How to do this?
}
}
public class BusinessObject
{
public static string MyStaticMethod()
{
return "blah";
}
}
Is there a correct object oriented approach to accomplishing this or will I need to resort to reflection?
EDIT: I went too far in trying to oversimplify this for the question and left out an important point. MyStaticMethod uses reflection and needs the derived type to return the correct results. However, I just realized another flaw in my design which is that I can't have a static virtual method and I think that's what I would need.
Looks like I need to find another approach to this problem altogether.
You can't access a static method through a generic type parameter even if it's constrained to a type. Just use the constrained class directly
var s = BusinessObject.MyStaticMethod();
Note: If you're looking to call the static method based on the instantiated type of O that's not possible without reflection. Generics in .Net statically bind to methods at compile time (unlike say C++ which binds at instantiation time). Since there is no way to bind statically to a static method on the instantiated type, this is just not possible. Virtual methods are a bit different because you can statically bind to a virtual method and then let dynamic dispatch call the correct method on the instantiated type.
The reason you can't reference the static member like this:
O.MyStaticMethod();
Is because you don't know what type O is. Yes, it inherits from BusinessObject, but static members are not inherited between types, so you can only reference MyStaticMethod from BusinessObject.
If you are forcing O to inherit from BusinessObject, why not just call it like this:
void SomeMethod()
{
var s = BusinessObject.MyStaticMethod(); // <- How to do this?
}
I have a list of class names and methods that can only be read during runtime. Is it possible to create a class dynamically like that? I'm currently using C# 4.0.
It is a little unclear whether you want to define a type at runtime and define methods against it, or whether you want to create an instance of an already-written type, and call methods on it.
Fortunately both are possible.
The second scenario is more likely, so you'd want to look at reflection (below) - but note that there are performance penalties associate with this (and small things like "what arguments does the method take" become very important).
For the first scenario, you'd need to look at TypeBuilder, but that is much more complex. Another option would be CSharpCodeProvider and dynamic assembly loading, but again - not trivial by any stretch.
using System;
namespace MyNamespace {
public class Foo {
public void Bar() {
Console.WriteLine("Foo.Bar called");
}
}
}
class Program {
static void Main() {
string className = "MyNamespace.Foo, MyAssemblyName",
methodName = "Bar";
Type type = Type.GetType(className);
object obj = Activator.CreateInstance(type);
type.GetMethod(methodName).Invoke(obj, null);
}
}
To include parameters (comments) you pass an object[] instead of the null:
using System;
namespace MyNamespace {
public class Foo {
public void Bar(string value) {
Console.WriteLine("Foo.Bar called: " + value);
}
}
}
class Program {
static void Main() {
string className = "MyNamespace.Foo, MyAssemblyName",
methodName = "Bar";
Type type = Type.GetType(className);
object obj = Activator.CreateInstance(type);
object[] args = { "hello, world" };
type.GetMethod(methodName).Invoke(obj, args);
}
}
If you are doing this lots (for the same method) there is a way to improve performance via a typed delegate, but this doesn't gain you much for occasional calls.
You can use the IL emit functionality straight out of the .Net framework to accomplish this. You will need to learn IL in order to dynamically generate type information at runtime--this is not for the feint of heart.
Introduction to Creating Dynamic Types with System.Reflection.Emit
As I can't really answer that you are asking I will answer a number of question you might want to ask.
Can I create an instance of class and call its method where both class and method are specified at run time?
Sure. The simple way first. Use a if statements:
var className = "MyClass";
var methodName = "MyMethod";
if (className == typeof(MyClass).Name) {
var instance = new MyClass();
if (methodName == "MyMethod")
instance.MyMethod();
if (methodName == "MyOtherMethod")
instance.MyOtherMethod();
}
Alternatively, you can use Activator.CreateInstance to create an instance of a class for you.
var className = "MyClass";
var methodName = "MyMethod";
//Get a reference to the Assembly that has the desired class. Assume that all classes that we dynamically invoke are in the same assembly as MyClass.
var assembly = typeof(MyClass).Assembly;
//Find the type that we want to create
var type = assembly.GetTypes().FirstOrDefault(t=>t.Name == className);
if(type != null) {
//Create an instance of this type.
var instance = Activator.CreateInstance(type);
//Find the method and call it.
instance.GetType().GetMethod(methodName).Invoke(instance);
}
Can I generate a class at run time?
Yes you can but it's hard. If you are an experienced C# programmer, know a bit of C++ and assembly, you should be able to grock it. If not, don't bother.
Microsoft provides a library to emit Intermediate Language code called, surpose, IL.Emit. There are very few problems that warrant using this method, amongst those are mock object generation and some aspects of Dependency Injection. It is quite likely that your problem is better solved in another fashion.
I'm trying to create a function in C# which will allow me to, when called, return a reference to a given class type. The only types of functions like this that I have seen are in UnrealScript and even then the functionality is hard coded into its compiler. I'm wondering if I can do this in C#. Here's what I mean (code snippet from UnrealScript source):
native(278) final function actor Spawn
(
class<actor> SpawnClass,
optional actor SpawnOwner,
optional name SpawnTag,
optional vector SpawnLocation,
optional rotator SpawnRotation
);
Now in UScript you would call it like this...
local ActorChild myChildRef; //Ref to ActorChild which Extends 'actor'
myChildRef = Spawn(class'ActorChild' ...); //rest of parameters taken out
myChildRef.ChildMethod(); //method call to method existing inside class 'ActorChild'
Which will return a reference to an object of class 'ActorChild' and set it to variable 'myChildRef.' I need to do something similar within C#.
I've looked into Generics but it seems that to use them, I need create an instace of the class where my function lies and pass the 'generic' parameter to it. This isn't very desirable however as I won't need to use the 'Spawn' function for certain classes but I would still need to add the generic parameter to the class whenever I use it.
I guess a simplified question would be, how can I return a type that I do not know at compile time and when the different classes could be far too many to trap.
Pseudo-Code (sticking to UScript class names, i.e. Actor):
//Function Sig
public class<Actor> Create(class<Actor> CreatedClass)
{
return new CreatedClass;
}
//Function call
ActorChild myChild = Create(class'ActorChild');
Any ideas?
EDIT: I would like to avoid explicit typecasts that would occur from the class calling Created. If I can typecast to the desired object within the Created method and return the 'unknown type' whatever that may be, I would be extremely happy.
EDIT 2: Thanks for your answers.
Rather than use a generic class, use a generic method:
public T Spawn<T>() where T : new()
{
return new T();
}
Having said that, I assume you want to do more than just blindly create an instance, otherwise you could just call new MyClass() yourself.
You can use the class System.Type to represent classes. To get references to type objects, you either use typeof (in a scope where the class is actually defined)
System.Type t = typeof(ActorChild);
or the Type.GetType function (if you only know the name of the type)
System.Type t = Type.GetType("NamespaceFoo.ActorChild");
You can then use the reflection API to create an instance
public object Create(System.Type ClassToCreate)
{
return ClassToCreate.GetConstructor(Type.EmptyTypes).Invoke(null);
}
What you're trying to accomplish can be done quite easily with Reflection and something called Dynamic Method Invocation.
Basically, you'll be using the Type object, the Activator.CreateInstance Method and some other nice classes like MethodInfo and ParameterInfo.
Here's an example to get you started:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace Reflection
{
class SomeClass
{
private string StringPrimer = "The parameter text is: ";
public SomeClass(string text)
{
Console.WriteLine(StringPrimer + text);
}
public string getPrimer() //supplies the Primer in upper case, just for kicks
{
return StringPrimer.ToUpper();
}
}
class Program
{
static void Main(string[] args)
{
SomeClass s = new SomeClass("this is an example of the classes normal hard-coded function.\nNow try feeding in some text");
string t = Console.ReadLine();
Console.WriteLine("Now feed in the class name (SomeClass in this case)");
Type myType = Type.GetType("Reflection."+Console.ReadLine()); //Stores info about the class.
object myClass = Activator.CreateInstance(myType, new object[] { t }); //This dynamically calls SomeClass and sends in the text you enter as a parameter
//Now lets get the string primer, using the getPrimer function, dynamically
string primer = (string)myType.InvokeMember("getPrimer",
BindingFlags.InvokeMethod | BindingFlags.Default,
null,
myClass,
null); //This method takes the name of the method, some Binding flags,
//a binder object that I left null,
//the object that the method will be called from (would have been null if the method was static)
//and an object array of parameters, just like in the CreateInstance method.
Console.WriteLine(primer);
}
}
}