제목처럼 : 리플렉션은 현재 실행중인 메소드의 이름을 알려줍니다.
나는 Heisenberg 문제 때문에 추측하지 않는 경향이 있습니다. 현재 메소드를 변경하지 않고 현재 메소드를 알려주는 메소드를 어떻게 호출합니까? 그러나 누군가가 나를 잘못 증명할 수 있기를 바랍니다.
최신 정보:
- 2 부 : 속성의 코드 내부를 살펴볼 수 있습니까?
- 3 부 : 성능은 어떻습니까?
최종 결과
MethodBase.GetCurrentMethod ()에 대해 배웠습니다. 또한 스택 추적을 만들 수있을뿐만 아니라 원하는 경우 필요한 정확한 프레임 만 만들 수 있다는 것도 알게되었습니다.  
속성 내에서 이것을 사용하려면 .Substring (4)를 사용하여 ‘set_’또는 ‘get_’을 제거하십시오.
답변
.NET 4.5 부터는 [CallerMemberName]을 사용할 수도 있습니다 .
예 : 속성 설정 기 (2 부 답변) :
    protected void SetProperty<T>(T value, [CallerMemberName] string property = null)
    {
        this.propertyValues[property] = value;
        OnPropertyChanged(property);
    }
    public string SomeProperty
    {
        set { SetProperty(value); }
    }컴파일러는 호출 사이트에서 일치하는 문자열 리터럴을 제공하므로 기본적으로 성능 오버 헤드가 없습니다.
답변
async방법이 아닌 경우 사용할 수 있습니다
System.Reflection.MethodBase.GetCurrentMethod().Name;https://docs.microsoft.com/en-us/dotnet/api/system.reflection.methodbase.getcurrentmethod
async메소드의 경우 “MoveNext”가 리턴 됨을 기억하십시오 .
답변
Lex가 제공 한 스 니펫은 약간 길어서 다른 사람이 정확히 동일한 기술을 사용하지 않았기 때문에 중요한 부분을 지적하고 있습니다.
string MethodName = new StackFrame(0).GetMethod().Name;이것은 동일한 결과를 MethodBase.GetCurrentMethod (). Name 기술에 반환해야 하지만 이전 방법에 대해 색인 1을 사용하여 자체 메소드로 한 번 구현 하고 여러 가지 다른 속성에서 호출 할 수 있기 때문에 여전히 주목할 가치가 있습니다. 또한 전체 스택 추적 대신 하나의 프레임 만 반환합니다.
private string GetPropertyName()
{  //.SubString(4) strips the property prefix (get|set) from the name
    return new StackFrame(1).GetMethod().Name.Substring(4);
}그것은 하나의 라이너이기도합니다.)
답변
빈 콘솔 프로그램의 Main 메소드 내에서 이것을 시도하십시오.
MethodBase method = MethodBase.GetCurrentMethod();
Console.WriteLine(method.Name);콘솔 출력 :
Main
답변
네 물론 이죠
객체를 조작하려면 실제로 다음과 같은 함수를 사용하십시오.
public static T CreateWrapper<T>(Exception innerException, params object[] parameterValues) where T : Exception, new()
{
    if (parameterValues == null)
    {
        parameterValues = new object[0];
    }
    Exception exception   = null;
    StringBuilder builder = new StringBuilder();
    MethodBase method     = new StackFrame(2).GetMethod();
    ParameterInfo[] parameters = method.GetParameters();
    builder.AppendFormat(CultureInfo.InvariantCulture, ExceptionFormat, new object[] { method.DeclaringType.Name, method.Name });
    if ((parameters.Length > 0) || (parameterValues.Length > 0))
    {
        builder.Append(GetParameterList(parameters, parameterValues));
    }
    exception = (Exception)Activator.CreateInstance(typeof(T), new object[] { builder.ToString(), innerException });
    return (T)exception;
}이 줄 :
MethodBase method     = new StackFrame(2).GetMethod();스택 프레임을 걸어 호출 메소드를 찾은 다음 리플렉션을 사용하여 일반 오류보고 기능을 위해 전달 된 매개 변수 정보 값을 얻습니다. 현재 방법을 얻으려면 현재 스택 프레임 (1)을 대신 사용하십시오.
다른 사람들이 현재 메소드 이름에 대해 말했듯이 다음을 사용할 수도 있습니다.
MethodBase.GetCurrentMethod()그 방법을 내부적으로 보면 단순히 StackCrawlMark를 생성하기 때문에 스택을 걷는 것이 좋습니다. 스택을 해결하는 것이 나에게 더 분명해 보입니다.
4.5 이후에는 메소드 매개 변수의 일부로 [CallerMemberNameAttribute]를 사용하여 메소드 이름의 문자열을 얻을 수 있습니다. 이는 일부 시나리오에서 도움이 될 수 있습니다 (그러나 실제로는 위의 예에서)
public void Foo ([CallerMemberName] string methodName = null)이것은 주로 이벤트 코드를 통해 문자열이 흩어진 INotifyPropertyChanged 지원을위한 솔루션 인 것 같습니다.
답변
LinqPad에서 임의의 타이밍 구성 을 사용하여 메소드 이름을 얻는 방법 비교 :
암호
void Main()
{
    // from http://blogs.msdn.com/b/webdevelopertips/archive/2009/06/23/tip-83-did-you-know-you-can-get-the-name-of-the-calling-method-from-the-stack-using-reflection.aspx
    // and /programming/2652460/c-sharp-how-to-get-the-name-of-the-current-method-from-code
    var fn = new methods();
    fn.reflection().Dump("reflection");
    fn.stacktrace().Dump("stacktrace");
    fn.inlineconstant().Dump("inlineconstant");
    fn.constant().Dump("constant");
    fn.expr().Dump("expr");
    fn.exprmember().Dump("exprmember");
    fn.callermember().Dump("callermember");
    new Perf {
        { "reflection", n => fn.reflection() },
        { "stacktrace", n => fn.stacktrace() },
        { "inlineconstant", n => fn.inlineconstant() },
        { "constant", n => fn.constant() },
        { "expr", n => fn.expr() },
        { "exprmember", n => fn.exprmember() },
        { "callermember", n => fn.callermember() },
    }.Vs("Method name retrieval");
}
// Define other methods and classes here
class methods {
    public string reflection() {
        return System.Reflection.MethodBase.GetCurrentMethod().Name;
    }
    public string stacktrace() {
        return new StackTrace().GetFrame(0).GetMethod().Name;
    }
    public string inlineconstant() {
        return "inlineconstant";
    }
    const string CONSTANT_NAME = "constant";
    public string constant() {
        return CONSTANT_NAME;
    }
    public string expr() {
        Expression<Func<methods, string>> ex = e => e.expr();
        return ex.ToString();
    }
    public string exprmember() {
        return expressionName<methods,string>(e => e.exprmember);
    }
    protected string expressionName<T,P>(Expression<Func<T,Func<P>>> action) {
        // https://stackoverflow.com/a/9015598/1037948
        return ((((action.Body as UnaryExpression).Operand as MethodCallExpression).Object as ConstantExpression).Value as MethodInfo).Name;
    }
    public string callermember([CallerMemberName]string name = null) {
        return name;
    }
}결과
반사
반사
스택
트레이스
인라인
상수 인라인 상수
상수
상수
expr
e => e.expr ()
exprmember
exprmember
발신자
메인
Method name retrieval: (reflection) vs (stacktrace) vs (inlineconstant) vs (constant) vs (expr) vs (exprmember) vs (callermember)
 154673 ticks elapsed ( 15.4673 ms) - reflection
2588601 ticks elapsed (258.8601 ms) - stacktrace
   1985 ticks elapsed (  0.1985 ms) - inlineconstant
   1385 ticks elapsed (  0.1385 ms) - constant
1366706 ticks elapsed (136.6706 ms) - expr
 775160 ticks elapsed ( 77.516  ms) - exprmember
   2073 ticks elapsed (  0.2073 ms) - callermember
>> winner: constant있습니다 expr및 callermember방법은 아주 “오른쪽”아니다. 여기 에서 리플렉션이 스택 트레이스보다 15 배 빠르다는 관련 주석 이 반복되는 것을 볼 수 있습니다 .
답변
편집 : MethodBase는 아마도 전체 호출 스택과 달리 현재 사용중인 메소드를 얻는 더 좋은 방법 일 것입니다. 그러나 여전히 인라인에 대해 걱정하고 있습니다.
메소드 내에서 StackTrace를 사용할 수 있습니다.
StackTrace st = new StackTrace(true);그리고 프레임을 살펴보십시오.
// The first frame will be the method you want (However, see caution below)
st.GetFrames();그러나 메소드가 인라인 된 경우 사용자가 생각하는 메소드 내부에 있지 않을 것입니다. 인라인을 방지하기 위해 속성을 사용할 수 있습니다.
[MethodImpl(MethodImplOptions.NoInlining)]