物业支持价值范围

Jon*_*art 18 c# properties

有可能这样吗?我假设没有,但它对我来说很好看:

class MyClass {
    public int Foo {
        get { return m_foo; }
        set {
            // Bounds checking, or other things that prevent the use
            // of an auto-implemented property
            m_foo = value;
        }

        // Put the backing field actually *in* the scope of the property
        // so that the rest of the class cannot access it.
        private int m_foo;
    }

    void Method() {
        m_foo = 42;    // Can't touch this!
    }
}
Run Code Online (Sandbox Code Playgroud)

当然我知道这个语法不正确,这不会编译.为了清楚地描绘我的想法,这是假设的未来C#.我为这个有点假设的问题道歉,但它对于Programmers.SE来说太具体了.

这样的东西可以在编译器中实现,它可以用于一个目的:只允许属性getset访问器查看字段,本质上允许属性是自包含的(如自动实现的属性),同时允许额外的get/set逻辑.

Eri*_*ert 31

简短的回答是否定的,今天在C#中是不可能的.

我们经常收到这样的功能请求; 它的更通用的形式是一个很好的功能.更一般的形式是为了更清楚地使寿命一个的本地变量正交其范围.

只是为了确保这些术语是明确的:变量是一个存储位置,可能是名称.每个变量都有一个生命周期:运行时保证变量引用有效存储的时间量.的范围一的名称是在其中可以使用该名称的文本的区域; 它是一个编译时的概念,而不是运行时概念.一个局部变量是一个变量,其范围是一个语句块.

在许多语言中,局部变量的生命周期与其范围密切相关:当控制在运行时逻辑上进入范围时,生命周期开始,当它离开范围时,生命周期结束.这在C#中也是如此,但有一些值得注意的警告:

  • 如果运行时可以确定这样做对托管代码对当前线程的操作没有影响,则可以扩展或截断本地的生存期.其他线程(如终结器线程)和当前线程上的非托管代码的操作是实现定义的.

  • 迭代器块,异步方法或匿名函数的封闭外部变量中的本地的生存期可以扩展为匹配或超过使用它的迭代器,任务,委托或表达式树的生命周期. .

显然,并不要求本地的生命和范围以任何方式捆绑在一起.如果我们可以明确地拥有具有实例或静态字段的生命周期的本地人,但是本地的范围,那将是很好的.C有这个功能; 你可以创建一个"静态"局部变量.C#没有.您的建议主要是允许属性块中的局部变量具有实例的生存期,但其范围仅限于块.

我会将此功能归类为"不错".我们有一个潜在的"好"功能列表,只要你的手臂我们没有时间实现,所以我不希望这一个很快就能到达列表的顶部.谢谢你的反馈; 它有助于我们在某种程度上优先考虑该列表.


Gro*_*ozz 6

这是我对此的看法:

public class WrappedField<T>
{
    public class Internals
    {
        public T Value;
    }

    private readonly Internals _internals = new Internals();
    private readonly Func<Internals, T> _get;
    private readonly Action<Internals, T> _set;

    public T Value
    {
        get { return _get(_internals); }
        set { _set(_internals, value); }
    }

    public WrappedField(Func<Internals, T> get, Action<Internals, T> set)
    {
        _get = get;
        _set = set;            
    }

    public WrappedField(Func<Internals, T> get, Action<Internals, T> set, T initialValue)
        : this(get, set)
    {
        _set(_internals, initialValue);
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

class Program
{
    readonly WrappedField<int> _weight = new WrappedField<int>(
        i => i.Value,           // get
        (i, v) => i.Value = v,  // set
        11);                    // initialValue

    static void Main(string[] args)
    {
        Program p = new Program();
        p._weight.Value = 10;

        Console.WriteLine(p._weight.Value);
    }
}
Run Code Online (Sandbox Code Playgroud)