如何通过反射获取当前属性名称?

Tom*_*ski 38 c# reflection properties

我想通过反射机制获取属性名称.可能吗?

更新:我有这样的代码:

    public CarType Car
    {
        get { return (Wheel) this["Wheel"];}
        set { this["Wheel"] = value; }
    }
Run Code Online (Sandbox Code Playgroud)

因为我需要更多这样的属性,我想做这样的事情:

    public CarType Car
    {
        get { return (Wheel) this[GetThisPropertyName()];}
        set { this[GetThisPropertyName()] = value; }
    }
Run Code Online (Sandbox Code Playgroud)

Ric*_*dOD 52

由于属性实际上只是方法,您可以执行此操作并清理返回的get_:

class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            var x = p.Something;
            Console.ReadLine();
        }

        public string Something
        {
            get
            {
                return MethodBase.GetCurrentMethod().Name;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

如果您对性能进行了分析,则应该找到MethodBase.GetCurrentMethod()比StackFrame快几英里.在.NET 1.1中,你也会在发布模式下遇到StackFrame的问题(从内存中我发现它发现它快了3倍).

这就是说我确信性能问题不会引起太多问题 - 尽管可以在这里找到有关StackFrame慢度的有趣讨论.

我想如果您担心性能,另一个选择是创建一个Visual Studio Intellisense代码片段,为您创建属性,并创建一个与属性名称对应的字符串.


tva*_*son 7

我想知道更多关于你需要它的上下文,因为在我看来你应该已经知道你在属性访问器中使用了什么属性.但是,如果必须,您可以使用MethodBase.GetCurrentMethod(). Name并删除之后的任何内容get_/set_.

更新:

根据您的更改,我会说您应该使用继承而不是反射.我不知道你的词典里有什么数据,但在我看来你真的想拥有不同的Car类,比如Sedan,Roadster,Buggy,StationWagon,不要把类型保存在局部变量中.然后你会有方法的实现,为那种类型的汽车做正确的事情.然后你可以简单地调用适当的方法,而不是找出你拥有的汽车类型,然后根据它的类型做出合适的方法.

 public interface ICar
 {
      void Drive( decimal velocity, Orientation orientation );
      void Shift( int gear );
      ...
 }

 public abstract class Car : ICar
 {
      public virtual void Drive( decimal velocity, Orientation orientation )
      {
          ...some default implementation...
      }

      public abstract void Shift( int gear );

      ...
 }

 public class AutomaticTransmission : Car
 {
       public override void Shift( int gear )
       {
          ...some specific implementation...
       }
 }

 public class ManualTransmission : Car
 {
       public override void Shift( int gear )
       {
          ...some specific implementation...
       }
 }
Run Code Online (Sandbox Code Playgroud)


Mik*_*chs 7

你提出的例子有点令人困惑,除非我没有得到它.从C#6.0开始,您可以使用nameof运算符.

public CarType MyProperty
{
    get { return (CarType)this[nameof(MyProperty)]};
    set { this[nameof(MyProperty)] = value]};
}
Run Code Online (Sandbox Code Playgroud)

如果你有一个方法来处理你的getter/setter,你可以使用C#4.5 CallerMemberName属性,在这种情况下你甚至不需要重复这个名字.

public CarType MyProperty
{
    get { return Get<CarType>(); }
    set { Set(value); }
}

public T Get<T>([CallerMemberName]string name = null)
{
    return (T)this[name];
}   

public void Set<T>(T value, [CallerMemberName]string name = null)
{
    this[name] = value;
}  
Run Code Online (Sandbox Code Playgroud)

  • 我每次都忘记了“ nameof”的魔力。与我看到的所有其他解决方案相比,仅调用`nameof(property)`会容易得多。确认只是执行`nameof(item.PropertyName)`对我来说是一种魅力。尽管对于其他人,具体情况可能会有所不同。 (2认同)

wei*_*ure 5

请改用MethodBase.GetCurrentMethod()!

反射用于处理在编译时无法完成的类型.获取您所在的属性访问者的名称可以在编译时决定,因此您可能不应该使用反射.

您可以使用调用堆栈中的访问器方法名称System.Diagnostics.StackTrace.

    string GetPropertyName()
    {
        StackTrace callStackTrace = new StackTrace();
        StackFrame propertyFrame = callStackTrace.GetFrame(1); // 1: below GetPropertyName frame
        string properyAccessorName = propertyFrame.GetMethod().Name;

        return properyAccessorName.Replace("get_","").Replace("set_","");
    }
Run Code Online (Sandbox Code Playgroud)