Determine Calling Object Type in C#

前端 未结 11 846
灰色年华
灰色年华 2021-02-05 14:37

Regardless of whether or not this is a good idea, is it possible to implement an interface where the executing function is aware of the calling object\'s type?

c         


        
相关标签:
11条回答
  • 2021-02-05 14:54

    You could examine the call stack, but that is both expensive and fragile. When your code is jit'ed the compiler might inline your methods so while it could work in debug mode you could get a different stack when compiled in release mode.

    0 讨论(0)
  • 2021-02-05 14:57

    I might be in trouble thinking I would handle this differently but....

    I assume this:

    class A calls on class E for information
    class C calls on class E for information
    both through the same method in E

    You know and created all three classes and can hide the content of class E to the public. If this were not the case, your controll would always be lost.

    Logically: if you can hide content of class E, you do this most likely by distributing through a DLL.

    If you do this anyway, why not hide the content of classes A and C as well (same method) but allowing A and C to be used as base for derived classes B and D.

    In classes A and C you would have a method to call the method in class E and deliver the result. In that method (usable by the derived class, but the content is hidden to the users) you can have long strings as "keys" passed to the method in class E. These strings could not be guessed by any user and would only be known to the base classes A, C and E.

    Having the base classes encapsulate the knowledge of how to call the method in E correctly would be perfect OOP implementation I think

    Then again... I could be overlooking the complexities here.

    0 讨论(0)
  • 2021-02-05 15:02

    Well you could try grabbing the stack trace and determine the type of the caller from there, which is an overkill in my opinion and would be slow.

    How about an interface, that A,B would implement?

    interface IFoo { 
         int Value { get; } 
    }
    

    And then your DoSomething method would look like this:

       public int DoSomething(int input, IFoo foo)
       {
            return input + foo.Value;
       }
    
    0 讨论(0)
  • 2021-02-05 15:04

    First, yes, it's a terrible idea to do this and breaks all kinds of solid design principles. You should definitely consider an alternative approach if that's open, like simply using polymorphism—this seems like it can be refactored to a pretty clear case of single dispatch.

    Secondly, yes, it's possible. Use System.Diagnostics.StackTrace to walk the stack; then get the appropriate StackFrame one level up. Then determine which method was the caller by using GetMethod() on that StackFrame. Note that building a stack trace is a potentially expensive operation, and it's possible for callers of your method to obscure where things are really coming from.


    Edit: This comment from the OP makes it pretty clear that this could probably be a generic or polymorphic method. @devinb, you might want to consider making a new question that provides more detail about what you're trying to do, and we can see if it lends itself well to a good solution.

    The short version is that I would end up have 30 or 40 identical functions that were simply off by one or two lines. – devinb (12 secs ago)

    0 讨论(0)
  • 2021-02-05 15:04

    Not reliably due to the possibility of inlining by the runtime.

    0 讨论(0)
提交回复
热议问题