Is there a way to determine which class called a static method in .NET

时间:2016-06-10 16:13:46

标签: c# asp.net .net

We have a central STATIC method that get's called from many different locations of our ASP.NET application.

I need to add some conditional logic to the static method that needs to run only if the method was called from a specific class. One approach would be to add an additional parameter to the static method's signature -- some kind of enum that would represent which class called this static method, but I was hoping .NET offered a more elegant approach.

EDIT: See Sample Code below

I am trying to modify how exceptions are handled. Currently, if we are processing 1000 checks, and there is an exception inside the loop at check 500, checks 500 - 1000 will not be processed.

We have several screens on our website that calls this central method. One of them called Check Creation Wizard, another called ACH Creation Wizard, etc. Well for the ACH Creation Wizard, we want to handle exceptions by simply skipping a failed check, and move on to the rest of the checks. However, for all other wizards, we want to continue failing the remaining batch of checks if one fails.

public static string GenerateChecks(List<CheckJob> checkJobs)
{
    foreach (CheckJob check in checkJobs)
    {
        try
        {
            bool didGenerate = DoGenerate(check);
            if(didGenerate)
            {
                Account acct = LoadAccount(check.GetParent());
                ModifyAccount(acct);
                SaveAcct(acct);
            }
        }           
        catch (Exception ex)
        {
            if (Transaction.IsInTransaction)
            {
                Transaction.Rollback();
            }

            throw;
        }
    }
}

5 个答案:

答案 0 :(得分:5)

这一切都远远闻到了。您可以通过多种方式实现此目的,但检测调用类是错误的方法。

为这个特定的其他类创建一个不同的静态方法,或者有一个额外的参数。

如果您坚持检测来电者,可以通过以下几种方式完成:

  1. 使用堆栈跟踪:

    var stackFrame = new StackFrame(1);
    var callerMethod = stackFrame.GetMethod();
    var callingClass = callerMethod.DeclaringType; // <-- this should be your calling class
    if(callingClass == typeof(myClass))
    {
       // do whatever
    }
    
  2. 如果使用.NET 4.5,则可以获得呼叫者信息。不是特定的类,但您可以在编译时获取调用者名称和源文件。使用[CallerMemberName][CallerFilePath]修饰的默认值添加参数,例如:

    static MyMethod([CallerFilePath]string callerFile = "")
    {
      if(callerFile != "")
      {
         var callerFilename = Path.GetFileName(callerFile);
         if(callerFilename == "myClass.cs")
         {
            // do whatever
         }
      }
    }
    
  3. 只需使用带有默认值的附加参数(或任何类型的不同签名)

  4. 请注意,1非常慢,2只是非常糟糕...所以为了更好:如果您需要不同的流程,请使用其他方法

    更新

    看完你的代码之后,你想要有两种不同的方法或一个参数就更清楚了......例如:

    public static string GenerateChecks(List<CheckJob> checkJobs, bool throwOnError = true)
    {
        //...
        catch (Exception ex)
        {
          if(throwOnError)
          {
            if (Transaction.IsInTransaction)
            {
               Transaction.Rollback();
            }
            throw;
          }
        }
    }
    

    然后将false传递给你想要继续前进

答案 1 :(得分:3)

你永远不会根据谁给你打电话做出决定。 您允许来电者通过提供功能来做出决定。

您希望单个方法在出错时执行两个不同的操作。所以要么(1)写两个方法,让调用者决定调用哪一个,或者(2)使方法采用改变其行为的布尔值,让调用者决定传递哪个布尔值,true或false。

答案 2 :(得分:1)

添加参数肯定更加优雅&#34;。使参数可选(通过提供默认值,例如boolfalse),并且只有在参数显式设置为true时才执行特殊代码。

另一种选择,虽然不是&#34;优雅&#34;正如您可以从评论中读到的那样,可以在StackTrace中搜索调用代码。

答案 3 :(得分:0)

我认为,您可以使用StackTrace类,但这种逻辑不是很好

答案 4 :(得分:0)

您可以像这样使用StackTrace

 static void Main(string[] args)
{
    Do();
}

static void Do()
{
    DosomethingElse();
}

private static void DosomethingElse()
{
    StackTrace stackTrace = new StackTrace();
    foreach (StackFrame Frame in stackTrace.GetFrames())
    {
        Console.WriteLine(Frame);
    }
}

这将是输出

{DosomethingElse at offset 77 in file:line:column <filename unknown>:0:0}
{Do at offset 37 in file:line:column <filename unknown>:0:0}
{Main at offset 40 in file:line:column <filename unknown>:0:0}
....
相关问题