Acessing在自动属性支持字段 [英] Acessing the backing field in an auto property

查看:119
本文介绍了Acessing在自动属性支持字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有什么办法来访问支持字段的属性,以做验证,变更跟踪等。?

Is there any way to access the backing field for a property in order to do validation, change tracking etc.?

是类似下面的可能吗?如果不是有没有计划把它在.NET 4.0 / C#4?

Is something like the following possible? If not is there any plans to have it in .NET 4 / C# 4?

public string Name
{
    get;
    set
    {
        if (value != <Keyword>)
        {
            RaiseEvent();
        }
        <Keyword> = value;
    }
}

主要的问题我已经是使用自动属性不允许的验证等,与一个明确的支持领域的属性相同的灵活性。然而,一个明确的支持领域有允许它被包含在访问时,应访问和重用验证的支持字段之类的一些情况的缺点,就这样也可以访问任何其他类等财产的变更跟踪物业外部。

The main issue I have is that using auto properties doesn't allow for the same flexibility in validation etc. that a property with a explicit backing field does. However an explicit backing field has the disadvantage in some situations of allowing the class it is contained in to access the backing field when it should be accessing and reusing the validation, change tracking etc. of the property just like any other class that may be accessing the property externally.

在上面的访问支持字段的例子是作用域属性这样属性验证preventing规避,变更跟踪等。

In the example above access to the backing field would be scoped to the property thus preventing circumvention of the property validation, change tracking etc.

编辑:我变&LT;支持字段>到&lt;关键字>。我会提出类似值的新关键字。 字段会做很好,虽然我敢肯定它是被在许多现有的code使用。

I've changed < Backing Field > to < Keyword >. I would propose a new keyword similar to value. field would do nicely although I'm sure it's being used in a lot of existing code.

推荐答案

看了你的迈赫达德的答复意见,我想我明白你的问题会好一点。

Having read your comments in Mehrdad's answer, I think I understand your problem a bit better.

看来,你所关心的开发商来访问他们正在编写的类中的私有状态的能力,绕过您的验证逻辑等,这表明国家不应该被包含在类的。

It appears that you are concerned about the ability of the developer to access private state in the class they are writing, bypassing your validation logic, etc. This suggests that the state should not be contained in the class at all.

我建议以下策略。编写重新presents一个ValidatedValue一个泛型类。此类包含只有后盾值,而只允许访问/突变通过get和set方法。委托传递给ValidatedValue重新present验证逻辑:

I would suggest the following strategy. Write a generic class that represents a ValidatedValue. This class holds only the backing value and only allows access/mutation via get and set methods. A delegate is passed to the ValidatedValue to represent the validation logic:

public class ValidatedValue< T >
{
    private T m_val;
    public ValidationFn m_validationFn;

    public delegate bool ValidationFn( T fn );

    public ValidatedValue( ValidationFn validationFn )
    {
        m_validationFn = validationFn;
    }

    public T get()
    {
        return m_val;
    }

    public void set(T v)
    {
        if (m_validationFn(v))
        {
            m_val = v;
        }
    }
}

您可以,当然,根据需要添加更多的代表(如支持pre /后更改通知)。

You could, of course, add more delegates as required (eg, to support pre/post change notification).

您的类现在将使用ValidatedValue代替后备存储,为您的财产。

Your class would now use the ValidatedValue in place of a backing store for your property.

下面的例子显示了一个类,MyClass的,有一个整数,验证小于100。注意,逻辑抛出一个例外是在MyClass的,不是ValidatedValue。这可以让你做到这一点取决于包含在MyClass的其他国家复杂的验证规则。 LAMBDA符号被用来构造验证委托 - 您可以有绑定到一个成员函数,而不是

The example below shows a class, MyClass, with an integer that is validated to be less than 100. Note that the logic to throw an exception is in MyClass, not the ValidatedValue. This allows you to do complex validation rules that depend on other state contained in MyClass. Lambda notation was used to construct the validation delegate - you could have bound to a member function instead.

public partial class MyClass
{
    private ValidatedValue<int> m_foo;

    public MyClass()
    {
        m_foo = new ValidatedValue<int>(
            v => 
            {
                if (v >= 100) RaiseError();
                return true;
            }
        );
    }

    private void RaiseError()
    {
        // Put your logic here....
        throw new NotImplementedException();
    }

    public int Foo
    {
        get { return m_foo.get(); }
        set { m_foo.set(value); }
    }
}

希望有所帮助 - 有点掉原来的话题,但我认为它更内嵌您的实际关注。我们所做的是从财产所采取的验证逻辑走,并把它的数据,这也正是你想要的。

Hope that helps - somewhat off the original topic, but I think it's more inline with your actual concerns. What we have done is taken the validation logic away from the property and put it on the data, which is exactly where you wanted it.

这篇关于Acessing在自动属性支持字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆