I am looking for an algorithm that can get the object that called the method, within that method.
For instance:
public class Class1 {
public void Method () {
//the question
object a = ...;//the object that called the method (in this case object1)
//other instructions
}
}
public class Class2 {
public Class2 () {
Class1 myClass1 = new Class1();
myClass1.Method();
}
public static void Main () {
Class2 object1 = new Class2();
//...
}
}
Is there any way to do this?
Here's an example of how to do this...
...
using System.Diagnostics;
...
public class MyClass
{
/*...*/
//default level of two, will be 2 levels up from the GetCaller function.
private static string GetCaller(int level = 2)
{
var m = new StackTrace().GetFrame(level).GetMethod();
// .Name is the name only, .FullName includes the namespace
var className = m.DeclaringType.FullName;
//the method/function name you are looking for.
var methodName = m.Name;
//returns a composite of the namespace, class and method name.
return className + "->" + methodName;
}
public void DoSomething() {
//get the name of the class/method that called me.
var whoCalledMe = GetCaller();
//...
}
/*...*/
}
Posting this, because it took me a while to find what I was looking for myself. I'm using it in some static logger methods...
You could get to the current stack trace in code and walk up one step.
http://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace.aspx
But as was commented below, this will get you the method and class calling you, but not the instance (if there is one, could be a static of course).
or just pass the object as method parameter.
public void Method(object callerObject)
{
..
}
and call the Method:
myClass.Method(this);
regards, Florian
It would be very bad style since
a) that would break encapsulation
b) it's impossible to know the type of the calling object at compile-time so whatever you do with the object later, it will propably not work.
c) it would be easier/better if you'd just pass the object to the constructor or the method, like:
Class1 c1 = new Class1(object1);
Obviously i don't know the exact details of your situation but this really seems like you need to rethink your structure a bit.
This could easily be done if proper inheritance is structured.
Consider looking into an abstract class and classes that inherit from said abstract class. You might even be able to accomplish the same thing with interfaces.
Related
I would like to create a function that returns new object according to the parameter, for example:
Base Class:
class BaseClass
{
public int x;
}
Class One:
class TestClassOne: BaseClass
{
public TestClassOne()
{
this.x = 1;
}
}
Class Two:
class TestClassTwo: BaseClass
{
public TestClassOne()
{
this.x = 2;
}
}
Main:
static void Main(string[] args)
{
BaseClass bc = GetConstructor("TestClassOne");
Console.WriteLine(bc.x); //Prints 1
}
static BaseClass GetConstructor(string className)
{
if(className.Equals("TestClassOne"))
{
return new TestClassOne();
}
else if(className.Equals("TestClassTwo"))
{
return new TestClassTwo();
}
return null;
}
The code I wrote works well, the problem is when I will have a lot of derived classes like TestClassThree, TestClassFour... TestClassThousand.
How can I make a function that returns the correct constructor without if else or switch case and etc?
I think that reflection would be a good option but I'm not really sure how to use it.
Thanks!
It would be best if you can use a generic method, lik in the answer of René, but you are using strings, so it doesn't seem so.
There are two steps:
Get the correct type;
Create an instance.
This is the minimal code necessary:
Type t = Assembly.GetExecutingAssembly().GetType("SO.BaseClass");
object o = Activator.CreateInstance(t);
As you can see, you need to know the assembly and the namespace of the type, or you will have to do some fuzzy matching on either.
I would offer a word of caution with your implementation. What you are attempting to do is called a factory. Considering the fact that you are adding a dependency for a base class, you will be limited to only allowing constructors with that base class. If you ever needed certain classes to have a different base class but be offered through the same method, you would need to share an interface instead. Like others have suggested, you can use generics. Here is an example without generics:
public static IMyInterface GetMatchingClass(string className)
{
Type t = Type.GetType(className);
return (IMyInterface)Activator.CreateInstance(t);
}
As long as the classes you return implement the given interface, all is peachy.
Currently I have something like this:
public abstract class Base {...}
public class Derived<T> : Base {...}
class Visitor {
public static void Visit<T>(Derived<T> d) {
...
}
}
My question is, given a Base reference that I know is a Derived instance, how can I apply that Visit function to that object, using the correct generic instantiation? I understand that the answer will probably involve a type-checked dynamic downcast, to make sure that the object isn't some other type derived from base, which is all fine. I assume the answer involves reflection, which is also fine, though I'd prefer if there was a way to do it without reflection.
It's also ok if the answer involves an abstract method on Base and Derived; I do have enough control of the classes to add that. But at the end of the day, I need to call a generic function, correctly instantiated with the T of the Derived type.
Sorry if this is an easy question; I come from a C++ background, where my instinct would be to use a CRTP or something else like that, which isn't possible in C#.
EDIT:
Here's an example of what I need to be able to do:
Base GetSomeDerivedInstance() { ...; return new Derived<...>(); }
var b = GetSomeDerivedInstance();
// This is the line that needs to work, though it doesn't necessarily
// need to have this exact call signature. The only requirement is that
// the instantiated generic is invoked correctly.
Visitor.Visit(b);
In my opinion, answers involving double-dispatch and More Classes are going to be superior than using reflection to do what inheritance should do for you.
Normally this means defining an 'accept' method on the visitable class, which simply calls the correct Visit method from the visitor.
class Base
{
public virtual void Accept(Visitor visitor)
{
visitor.Visit(this); // This calls the Base overload.
}
}
class Derived<T> : Base
{
public override void Accept(Visitor visitor)
{
visitor.Visit(this); // this calls the Derived<T> overload.
}
}
public class Visitor
{
public void Visit(Base #base)
{
...
}
public void Visit<T>(Derived<T> derived)
{
...
}
}
Then you can do what you mentioned in your question, with a small modification:
Base b = createDerived();
b.Accept(new Visitor());
If your visit method is a static class that you can't change for whatever reason, you could always wrap this into a dummy instance visitor class which calls the right static method.
(Edited for clarity)
The following will use a variable called "anyvalue" whose type is only known at run-time. Then we'll create an instance of your Derived class based on the type of anyvalue. Once we have that instance, we can use reflection to get the correct Visit method.
var anyvalue = 5; // This value could have come from anywhere.
...
var derivedType = typeof (Derived<>).MakeGenericType(anyvalue.GetType());
var dvalue = Activator.CreateInstance(derivedType);
var method = typeof(Visitor).GetMethod("Visit");
var genericMethod = method.MakeGenericMethod(new[] { anyvalue.GetType() });
genericMethod.Invoke(null, new [] { dvalue });
What is a little confusing is that this is a skeletal example and you do not use the original value for anything other than getting a run-time type. In the real world implementation, I would assume a constructor would use that value to set internal state in the Derived instance. That is not covered here because that is not part of the question that was asked.
UPDATE:
I think this will do what you want. Note that I created the itemarray so that we would have some run-time values. They have to be created somewhere. So whether they are passed in as object[] or provided some other way, they had to be constructed with a type specifier somewhere. Also, this assumes that Derived<> is the only derived class. Otherwise, this is not safe code.
var itemarray = new Base[] { new Derived<int>(), new Derived<string>() };
foreach (var baseObject in itemarray)
{
var derivedType = baseObject.GetType();
var visitMethod = typeof(Visitor)
.GetMethod("Visit")
.MakeGenericMethod(derivedType.GetGenericArguments());
visitMethod.Invoke(null, new[] { baseObject });
}
The Accept approach does seem a bit more manageable. My goal was to answer the question you asked without passing judgment on your approach. I have needed to use this approach several times. I wrote an entity framework about 9 years ago. I had a really hard time doing exactly what you are trying to do. I created base classes that were not generic so that I could share basic functionality regardless of the generic type. It proved challenging. I am not sure I would do it the same way now. I'd probably investigate a few patterns just as you are doing.
You should be able to do something like the following:
Base foo = new Derived<int>();
var method = typeof(Visitor).GetMethod("Visit", BindingFlags.Public | BindingFlags.Static);
method.MakeGenericMethod(foo.GetType().GenericTypeArguments.First()).Invoke(null, new[] {foo});
Perhaps you're meaning something like this?
public class Derived<T>
{
}
public abstract class Derivable<T>
{
public Derived<T> CreateDerived()
{
return new Derived<T>();
}
}
public class Foo : Derivable<Foo>
{
}
class Visitor
{
public static void Visit<T>(Derived<T> obj)
{
Console.Out.WriteLine("Called!");
}
}
void Main()
{
var obj = new Foo();
var derived = obj.CreateDerived();
Visitor.Visit(derived);
}
If the creation of the Derived<T> is T-specific, then you'd make the CreateDerived method abstract and implement it for each T. Or use an IDerivable<T> interface instead if you don't want it as your base class.
I want instantiate complete class.
I have the Type of class which I want to instantiate.
Activator.createInstance(type) I created Instance.
I searched all field of this instance.
I have a field which is defined in another assembly so I load that and instantiate it.
Again I repeat step 3 and 4 for fields inside that class (nested)
I am creating an instance of every type
//in a1.dll
class class1
{
class2 var1;
//some Method
}
//in a2.dll
class class2
{
class3 var2;
//some Method
}
//in a3.dll
class class3
{
//some Method
}
I have to create instance of the entire class1 type.
So you want to create a class containing other classes.
Here is what you can do:
create a class instance through the Activator class
for each property and field type in the current instance, create a sub instance by calling the method you are in and assign the sub instance to the current instance field or property
The following code may help you start getting a handle on this problem, but please read it carefully, as well as the very important points under it:
public class A
{
public B MyBProperty { get; set; }
public C MyCField;
}
public class B
{
public C MyCField;
}
public class C
{
}
public class Creator
{
static MethodInfo mi;
static Creator()
{
mi = typeof(Creator).GetMethod("Create");
}
public T Create<T>()
{
var createdType = Activator.CreateInstance<T>();
// assign all properties
foreach (var p in typeof(T).GetProperties())
{
try
{
var mig = mi.MakeGenericMethod(p.PropertyType);
p.SetValue(createdType, mig.Invoke(this, null));
}
catch
{
}
}
// assign all fields
foreach (var f in typeof(T).GetFields())
{
try
{
var mig = mi.MakeGenericMethod(f.FieldType);
f.SetValue(createdType, mig.Invoke(this, null));
}
catch
{
}
}
return createdType;
}
}
// to use it:
var c = new Creator();
var a = c.Create<A>(); // should be instantiated
Now for some very important points:
this code is supposed to help you see how you can start, it is very naive
it doesn't check for infinite loops !!!
it doesn't cache any creation mechanisms
it fails if your class cannot be created, for example because it doesn't have a parameterless constructor
it fails silently
don't use it!
There are plenty of ways to automagically create objects, and this code is not a solid example, merely a starting point: if you want to know more, I would recommend reading the code from Autofixture or any other automatic object creation framework. I just hope it will help you look into the right direction.
Is it possible to reflect on an explicit interface implementation from the call stack? I want to use this info to look up an attribute on the interface itself.
Given this code:
interface IFoo
{
void Test();
}
class Foo : IFoo
{
void IFoo.Test() { Program.Trace(); }
}
class Program
{
static void Main(string[] args)
{
IFoo f = new Foo();
f.Test();
}
public static void Trace()
{
var method = new StackTrace(1, false).GetFrame(0).GetMethod();
// method.???
}
}
Specifically, in Trace(), I would like to be able to get to typeof(IFoo) from method.
In the watch window, if I look at method.ToString() it gives me Void InterfaceReflection.IFoo.Test() (InterfaceReflection is the name of my assembly).
How can I get to typeof(IFoo) from there? Must I use a name-based type lookup from the assembly itself, or is there a Type IFoo hidden somewhere in the MethodBase?
UPDATE:
Here's the final solution, thanks to Kyte
public static void Trace()
{
var method = new StackTrace(1, false).GetFrame(0).GetMethod();
var parts = method.Name.Split('.');
var iname = parts[parts.Length - 2];
var itype = method.DeclaringType.GetInterface(iname);
}
itype will have the interface type for the implementing method. This will only work with explicit interface implementations, but that's exactly what I need. Now I can use itype to query attributes attached to the actual interface type.
Thanks to everyone for their help.
Testing around with VS2010, I found DeclaringType, which gets the object type that contains the method, from where you can get the interfaces as Type objects.
public static void Trace() {
var stack = new StackTrace(1, true);
var frame = stack.GetFrame(0);
var method = frame.GetMethod();
var type = method.DeclaringType;
Console.WriteLine(type);
foreach (var i in type.GetInterfaces()) {
Console.WriteLine(i);
}
}
Returns:
TestConsole.Foo
TestConsole.IFoo
(I called the project TestConsole)
method will be a System.Reflection.RuntimeMethodInfo, which is a class derived from System.Reflect.MethodBase. You could e.g. call Invoke() on it (though if you did so at the point where you obtained it, then this is going to result in an infinite recursion that eventually dies by overflowing the stack).
Calling ToString() on it returns a fully qualified name. Did you call the project InterfaceReflection?
Not sure what more you want than that.
Edit: Okay, now I do. To find the declaring type look at the DeclaringType property, this will return the class on which the method was declared (which could be the class it was called on, or a base class):
So far so easy, this returns a Type object for Foo.
Now for the tricky bit, because you care about the interface it was declared on. However, there could be more than one interface that defined a method with precisely the same signature, which means the simple question "if this came from an interface, what was that interface?" doesn't always have a single answer.
There may be a neater way to do this, but all I can think of is calling GetInterfaces() on the Type object you got from DeclaringType, and then looking for one whose name matches the method's signature.
I don't want to presume too much, but in this case, it looks like you may be causing some confusion because Foo and Program are inter-dependent. Typically, I would think Program would "own" Foo (which would be agnostic of Program) in such a way that it's responsible for setting the delegate so reflection could likely be avoided...the way you have it set up, Foo "owns" (actually, I guess depends on is probably more accurate) Program in a way (because it's hardcoing a a call to its Program.Trace() ), and Program "owns" Foo in a way (because it controls the instance).
I don't know if this would work in your particular scenerio, but it looks like an event type operation might make more sense and handle the communication more simply.
ETA: Code sample:
public interface IFoo
{
event EventHandler Testing;
void Test();
}
public class Foo : IFoo
{
public event EventHandler Testing;
protected void OnTesting(EventArgs e)
{
if (Testing != null)
Testing(this, e);
}
public void Test()
{
OnTesting(EventArgs.Empty);
}
}
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
IFoo f = new Foo();
f.Testing += new EventHandler(f_Testing);
f.Test();
}
static void f_Testing(object sender, EventArgs e)
{
IFoo foo = sender as IFoo;
if (foo != null)
{
//...
}
}
}
I might be misunderstanding your question, though.
I think .NET appends the full name to the front of the MethodInfo.Name property so that it has a unique name for each method. Think of:
interface IFoo
{
void Test();
}
interface IFoo2
{
void Test();
}
class Foo : IFoo, IFoo2
{
void IFoo.Test() { Trace(); }
void IFoo2.Test() { Trace(); }
}
In this case, typeof(Foo).GetMethods() would return both Test() methods but their names would conflict, so I guess they appended the interface name to make them unique?
The MethodInfo.DeclaringType returns the type that contains the implementation. So if IFoo were actually some base type instead of an interface, and there was a base method declaration there, then .DeclaringType would return the type of the base class.
Interestingly, I can't seem to find the actual interface name anywhere in the MethodInfo either, so I guess you would have to look it up by name, something like:
public static void Trace()
{
var method = new System.Diagnostics.StackTrace(1, false).GetFrame(0).GetMethod();
var fromType = method.DeclaringType;
if (method.Name.Contains("."))
{
var iname = method.Name.Substring(0, method.Name.LastIndexOf('.'));
fromType = Type.GetType(iname); // fromType is now IFoo.
}
}
In a non-static method I could use this.GetType() and it would return the Type. How can I get the same Type in a static method? Of course, I can't just write typeof(ThisTypeName) because ThisTypeName is known only in runtime. Thanks!
If you're looking for a 1 liner that is equivalent to this.GetType() for static methods, try the following.
Type t = MethodBase.GetCurrentMethod().DeclaringType
Although this is likely much more expensive than just using typeof(TheTypeName).
There's something that the other answers haven't quite clarified, and which is relevant to your idea of the type only being available at execution time.
If you use a derived type to execute a static member, the real type name is omitted in the binary. So for example, compile this code:
UnicodeEncoding.GetEncoding(0);
Now use ildasm on it... you'll see that the call is emitted like this:
IL_0002: call class [mscorlib]System.Text.Encoding
[mscorlib]System.Text.Encoding::GetEncoding(int32)
The compiler has resolved the call to Encoding.GetEncoding - there's no trace of UnicodeEncoding left. That makes your idea of "the current type" nonsensical, I'm afraid.
Another solution is to use a selfreferecing type
//My base class
//I add a type to my base class use that in the
//static method to check the type of the caller.
public class Parent<TSelfReferenceType>
{
public static Type GetType()
{
return typeof(TSelfReferenceType);
}
}
Then in the class that inherits it, I make a self referencing type:
public class Child: Parent<Child>
{
}
Now the call type typeof(TSelfReferenceType) inside Parent will get and return the Type of the caller without the need of an instance.
Child.GetType();
You can't use this in a static method, so that's not possible directly. However, if you need the type of some object, just call GetType on it and make the this instance a parameter that you have to pass, e.g.:
public class Car {
public static void Drive(Car c) {
Console.WriteLine("Driving a {0}", c.GetType());
}
}
This seems like a poor design, though. Are you sure that you really need to get the type of the instance itself inside of its own static method? That seems a little bizarre. Why not just use an instance method?
public class Car {
public void Drive() { // Remove parameter; doesn't need to be static.
Console.WriteLine("Driving a {0}", this.GetType());
}
}
I don't understand why you cannot use typeof(ThisTypeName). If this is a non-generic type, then this should work:
class Foo {
static void Method1 () {
Type t = typeof (Foo); // Can just hard code this
}
}
If it's a generic type, then:
class Foo<T> {
static void Method1 () {
Type t = typeof (Foo<T>);
}
}
Am I missing something obvious here?
When your member is static, you will always know what type it is part of at runtime. In this case:
class A
{
public static int GetInt(){}
}
class B : A {}
You cannot call (edit: apparently, you can, see comment below, but you would still be calling into A):
B.GetInt();
because the member is static, it does not play part in inheritance scenarios. Ergo, you always know that the type is A.
For my purposes, I like #T-moty's idea. Even though I have used "self-referencing type" information for years, referencing the base class is harder to do later.
For example (using #Rob Leclerc example from above):
public class ChildA: Parent<ChildA>
{
}
public class ChildB: Parent<ChildB>
{
}
Working with this pattern can be challenging, for example; how do you return the base class from a function call?
public Parent<???> GetParent() {}
Or when type casting?
var c = (Parent<???>) GetSomeParent();
So, I try to avoid it when I can, and use it when I must. If you must, I would suggest that you follow this pattern:
class BaseClass
{
// All non-derived class methods goes here...
// For example:
public int Id { get; private set; }
public string Name { get; private set; }
public void Run() {}
}
class BaseClass<TSelfReferenceType> : BaseClass
{
// All derived class methods goes here...
// For example:
public TSelfReferenceType Foo() {}
public void Bar(TSelfRefenceType obj) {}
}
Now you can (more) easily work with the BaseClass. However, there are times, like my current situation, where exposing the derived class, from within the base class, isn't needed and using #M-moty's suggestion just might be the right approach.
However, using #M-moty's code only works as long as the base class doesn't contain any instance constructors in the call stack. Unfortunately my base classes do use instance constructors.
Therefore, here's my extension method that take into account base class 'instance' constructors:
public static class TypeExtensions
{
public static Type GetDrivedType(this Type type, int maxSearchDepth = 10)
{
if (maxSearchDepth < 0)
throw new ArgumentOutOfRangeException(nameof(maxSearchDepth), "Must be greater than 0.");
const int skipFrames = 2; // Skip the call to self, skip the call to the static Ctor.
var stack = new StackTrace();
var maxCount = Math.Min(maxSearchDepth + skipFrames + 1, stack.FrameCount);
var frame = skipFrames;
// Skip all the base class 'instance' ctor calls.
//
while (frame < maxCount)
{
var method = stack.GetFrame(frame).GetMethod();
var declaringType = method.DeclaringType;
if (type.IsAssignableFrom(declaringType))
return declaringType;
frame++;
}
return null;
}
}
EDIT
This methods will works only when you deploy PDB files with the executable/library, as markmnl pointed out to me.
Otherwise will be a huge issue to be detected: works well in developement, but maybe not in production.
Utility method, simply call the method when you need, from every place of your code:
public static Type GetType()
{
var stack = new System.Diagnostics.StackTrace();
if (stack.FrameCount < 2)
return null;
return (stack.GetFrame(1).GetMethod() as System.Reflection.MethodInfo).DeclaringType;
}