C# 用于方法名称的预定义宏 在C++中,有预定义的宏,如代码>函数>函数>代码>,编译成宏使用的函数名的字符串文字。 void MyFunc() { printf("I'm in %s!", __FUNCTION__); // I'm in MyFunc! }

C# 用于方法名称的预定义宏 在C++中,有预定义的宏,如代码>函数>函数>代码>,编译成宏使用的函数名的字符串文字。 void MyFunc() { printf("I'm in %s!", __FUNCTION__); // I'm in MyFunc! },c#,asp.net,webforms,c-preprocessor,C#,Asp.net,Webforms,C Preprocessor,C#有类似的吗?我希望为asp.net web表单执行此操作: public string MyProperty { get { return (string)ViewState[__PROPERTY__]; } set { ViewState[__PROPERTY__] = value; } } 显然,这是行不通的(否则我不会问这个问题),我想知道C语言中是否有类似的东西,与使用字符串文字“MyProperty”相比,它不使用反射或对性能有任何负面影响 这将有望减少我这方面的

C#有类似的吗?我希望为asp.net web表单执行此操作:

public string MyProperty
{
    get { return (string)ViewState[__PROPERTY__]; }
    set { ViewState[__PROPERTY__] = value; }
}
显然,这是行不通的(否则我不会问这个问题),我想知道C语言中是否有类似的东西,与使用字符串文字
“MyProperty”
相比,它不使用反射或对性能有任何负面影响

这将有望减少我这方面的打字错误,但我可以想到一些其他情况下这将是有用的。

您可以使用获取当前方法的名称

StackTrace st = new StackTrace(); 
StackFrame sf = st.GetFrame(1);
string method = sf.GetMethod().ToString();
对于属性,返回的方法名称将包括magic
get\uu
set\u
前缀


<>但是,我认为你不能把这个重构成一个内嵌的宏或者函数,就像C++一样。但是如果你重构了一个实用的方法来解决这个问题,你可能只需要将StackTrace向后弹出一步来记录调用方的信息?

我不知道ASP.NET WebForms中是否有类似于
视图包的东西。万一没有,你也不难拥有它。然后,您可以将
ViewState
包装在该类中,并按照您的意愿获得常规属性成员访问权限

public class ExpandoViewState : DynamicObject
{
    private readonly StateBag _viewState;

    public ExpandoViewState(StateBag viewState)
    {
        _viewState = viewState;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        result = _viewState[binder.Name];
        if (result != null)
            return true;
        return base.TryGetMember(binder, out result);
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        _viewState[binder.Name] = value;
        return true;
    }
}

...

dynamic state = new ExpandoViewState(ViewState);
var val = (string)state.MyProperty;
state.MyProperty = "hi";

C的预处理器不支持与C++相关联的值的宏,但是你要做的事情可以通过编译器生成的C 5和更大的编译器(至少VS201+)来完成。具体来说,通过System.Runtime.CompilerServices命名空间中的CallerMemberNameAttribute。根据您的问题代码,我创建了以下示例,以说明如何着手做您想做的事情:

using System;

class ViewState
{
    public string this[string propertyName]
    {
        get { return propertyName; }
        set { }
    }
};
class View
{
    ViewState mState = new ViewState();

    static string GetCallerName(
        [System.Runtime.CompilerServices.CallerMemberName] string memberName = "")
    {
        return memberName;
    }

    public string MyProperty
    {
        get { return (string)mState[GetCallerName()]; }
        set { mState[GetCallerName()] = value; }
    }
};
class Program
{
    static void Main(string[] args)
    {
        var view = new View();
        Console.WriteLine(view.MyProperty);

        Console.ReadKey();
    }
};
“MyProperty”将打印到控制台。编译时,编译器将用调用构造的(属性、方法等)名称替换GetCallerName的memberName参数的默认值。所以程序员不需要代码维护


还应该注意的是,这还有一个额外的好处,就是可以很好地使用模糊处理工具,只要它们发生在编译后。

根据我使用C的经验,您可以使用诸如#if debug#endif之类的宏。但是,编译时宏不能包含任何内容。
\uuuuu FUNCTION\uuuu
用于编译为字符串文字(我认为是在gcc 2.96中),但多年来一直没有。这个变化有点痛苦。谢谢你的回答,但是我正在寻找更具性能的东西,最好是一些编译时发生的事情。@马修在编译时不会有用,因为你没有编译时定义的非文字值,就像你在C++中那样。您可以像键入此标识符一样轻松地键入实际的方法名称……也就是说,如果您是一名优秀的脚本编写者,您可以编写一个visual studio宏来用方法名称替换
\uuuuuu函数\uuuuuuu
。是否可以在带有
GetFrame(2)
的错误处理函数中使用此方法来获取调用方的名称?这似乎更有用,而且只会在需要时发生!