Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/grails/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取在C中调用该方法的实例#_C#_Class_Methods_Instance - Fatal编程技术网

C# 获取在C中调用该方法的实例#

C# 获取在C中调用该方法的实例#,c#,class,methods,instance,C#,Class,Methods,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 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();
        //...
    }

}

有什么方法可以做到这一点吗?

您可以在代码中找到当前堆栈跟踪,然后向上走一步。

但正如下面所评论的,这将得到调用您的方法和类,而不是实例(如果有实例,当然可能是静态的)。

这将是非常糟糕的风格,因为

a) 这将破坏封装
b) 在编译时不可能知道调用对象的类型,所以无论您以后如何处理该对象,它都可能无法工作。
c) 如果只将对象传递给构造函数或方法,会更容易/更好,如:

Class1 c1 = new Class1(object1);

或者只是将对象作为方法参数传递

public void Method(object callerObject)
{
..
}
并调用该方法:

myClass.Method(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();
        //...
    }
/*...*/
}

发布这篇文章,因为我花了一段时间才找到我想要的东西。我在一些静态记录器方法中使用它…

我有一个问题,一旦你有了它,你打算用它做什么?如果您需要获取调用对象的引用,那么为什么不将其作为参数传递?Dupe?我很好奇:用例是什么?你认为你为什么需要这样做?“我需要有一个算法,可以让对象[调用]方法[。]中的一个方法。”为什么?你用这个干什么?如果你详细说明你需要这个做什么,我们可能会在一个更好的位置帮助你解决你的问题。(这是一个典型的例子,“看起来你问错了问题。后退几步,因为你前一段时间似乎走错了路。”)这个问题可以给出所谓的答案。不是调用它的对象实例。您可能错了,但感谢您真正回答了这个问题。封装是编译器强制执行的一种语言功能。我们可以在运行时以各种方式破坏它(例如,使用反射我们可以修改私有字段)。这不是不可能的,因为它破坏了封装(很多事情都可以做到这一点)。正因为如此,这是一个非常糟糕的主意。:-)嗯,我宁愿说“不可能”,也不愿解释“这不是一个好主意,因为……”,然后得到的回答是“是的,是的,我没有听过你关于糟糕风格和其他方面的东西,我的想法听起来很酷,所以我会去做。”你更愿意说什么并不重要;你的答案是以事实上不正确的陈述为前提的。a)它不会破坏封装,就像将对象传递给方法一样。b) 知道物体的类型并非不可能。如果有对它的引用,只需调用.GetType()。c) 这会更容易。“更好”是一种价值判断,部分取决于API的设计目标和要求。当然,在速度上,使用传入引用比进行某种反射要好。我应该注意,这不会满足您的需要,因为您需要给定对象的实例。。。在这种情况下,您应该重新思考。在发布模式下运行此操作,编译器将优化调用堆栈,这将给您带来问题。在.NET4.5中,现在有了
CallerMemberName
属性,就是它!我真的不赞成像@lazarusmade(‘为什么你甚至需要这个’)这样的评论,更不赞成他们被提升投票率。我和你们一样需要这个,许多线程调用的静态记录器。这个答案被低估了,我正在寻找一种方法来做一些简单的日志记录,而不使用NLog、Log4Net等。我不知道我可以创建StackTrace,这个解决方案帮了我的忙。