当使用get和set时,我可以访问c#中的变量吗?

本文关键字:访问 变量 我可以 get set | 更新日期: 2023-09-27 18:14:03

当我在类中执行以下操作时:

public string ModifiedBy { get; set; }

c#如何存储数据。编译器是否生成一个后备变量,它是如何命名的,我是否可以访问它而不使用get;准备好了吗?

当使用get和set时,我可以访问c#中的变量吗?

是,编译器生成一个后备字段。

不,你不能在编译时访问它。

是的,你可以在运行时通过反射访问它。

不,你不应该。


访问属性的后备字段最简单的方法是,毫不奇怪,实现一个带有后备字段的属性:

private int _myInt;
public int MyInt {
    get { return _myInt; }
    set { _myInt = value; }
}

如果您想要自动实现属性的便利性,但不希望每个人都能够更改其值,那么将访问修饰符限制为它的一个或其他部分可能是合适的,即

public int MyInt { get; private set; } // or protected set etc

它将其存储在编译器生成的私有支持字段中。该字段被命名为<ModifiedBy>k__BackingField之类的东西,虽然可以通过反射找到它,但这样做不一定是个好主意。

如果您有特定的原因访问该字段,您应该更改该属性以使用带有定义的支持字段的显式实现。但是,由于根据定义,自动属性除了保存和检索该值之外什么也不做,如果您还没有使用更复杂的getter和setter,我可以认为没有理由需要访问该字段。

如果没有反射,您无法访问它,但是如果您-您可以这样做:

using System.Diagnostics;
using System.Linq;
using System.Reflection;
class Program
{
    internal class MyClass
    {
        public string MyProperty { get; set; }
    }
    static void Main(string[] args)
    {
        foreach (var mi in
                typeof(MyClass).GetMembers(BindingFlags.NonPublic | BindingFlags.Instance)
                    .Where(m => m is FieldInfo))
        {
            Debug.WriteLine(mi.Name);
        }
        MyClass o = new MyClass();
        var fi = (FieldInfo)typeof(MyClass).GetMember(
            "<MyProperty>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic)[0];
        fi.SetValue(o, "Success");
        Debug.WriteLine(o.MyProperty);
    }
}

输出如下:

<MyProperty>k__BackingField
Success

该语法用于自动实现的属性。备用变量是由编译器生成的,你不能访问它。

本质上是这样编译的:

private string __foo_1;   // Compiler-generated - cannot access.
public string ModifiedBy
{
    get { return __foo_1; }
    set { __foo_1 = value; }
}

理论上, public auto属性就像一个公共变量。正如许多人已经提到的;编译器将创建所需的私有变量来保存数据。如果您需要访问底层私有变量,请使用硬编码的变量名,以避免运行时异常。

然而在现实中我们需要创建auto属性以确保未来的开发不会破坏依赖于该程序集的应用程序。

将公共变量更改为属性是一个破坏性的更改。参考链接的博客以更好地理解它。

你不能。但问题是,你为什么要这么做?如果是速度问题,则不需要使用属性。否则,我真的没有理由认为您需要访问自动实现属性的支持变量,因为它们没有副作用,因此功能几乎与普通字段相同。