有什么方法可以访问属性的支持字段以进行验证、更改跟踪等?

像下面这样的事情可能吗?如果没有,是否有计划将其纳入 .NET 4 / C# 4?

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

我遇到的主要问题是使用自动属性不允许在验证等方面具有相同的灵活性。具有显式支持字段的属性可以做到这一点。然而,在某些情况下,显式支持字段的缺点是允许它包含的类在应该访问和重用验证、更改跟踪等时访问支持字段。该属性的属性就像可能从外部访问该属性的任何其他类一样。

在上面的示例中,对支持字段的访问将限定在属性范围内,从而防止规避属性验证、更改跟踪等。

编辑: 我已将 < 支持字段 > 更改为 < 关键字 >。我会提出一个类似于 value 的新关键字。 场地 尽管我确信它已在许多现有代码中使用,但效果会很好。

有帮助吗?

解决方案

已经阅读迈赫达德的回答您的意见,我想我明白你的问题好一点。

看来你是担心开发商在他们写的类访问私有状态的能力,绕过您的验证逻辑,等等。这表明,国家不应该在课堂上载的。

我建议以下策略。写一个表示ValidatedValue一个泛型类。该类只持有后盾值,而只允许访问/突变通过get和set方法。委托被传递到ValidatedValue来表示验证逻辑:

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;
        }
    }
}

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

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

下面的例子显示了一个类,MyClass的,与被验证的为小于100。注意,逻辑到抛出异常是在MyClass的,而不是ValidatedValue的整数。这可以让你做到这一点取决于包含在MyClass的其他国家复杂的验证规则。拉姆达符号被用于构建验证委托 - 你可能会结合到一个成员函数代替

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); }
    }
}

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

其他提示

没有没有。如果您要访问的支持字段,则不要使用自动属性,并推出自己的。

我同意,这将是巨大的,有一个字段是由班里的其他同学只能由属性访问,而不是。我会使用的所有的时间。

作为 微软软件定义网络 状态:

“在C#3.0及更高版本中,当属性访问者中不需要其他逻辑时,自动插入属性使属性 - 模具更加简洁。他们还启用客户端代码在声明属性如下所示时创建对象,编译器只能通过属性的GET和SET访问者访问私有的匿名备份字段。”

由于您的访问器中有额外的逻辑,因此在您的场景中使用自动实现的属性是不合适的。

虽然支持字段确实存在,但它被赋予了一个损坏的名称以阻止您轻松引用它 - 这个想法是您 切勿直接引用该字段. 。为了利益起见,您可以使用 Reflector 反汇编您的代码并发现字段名称,但我建议您不要直接使用该字段,因为该名称确实可能是不稳定的,因此您的代码可能随时崩溃。

没有,但你可以在子类:

public class Base
{
    public string Name
    {
        get;
        virtual set;
    }
}

public class Subclass : Base
{
    // FIXME Unsure as to the exact syntax.
    public string Name
    {
        override set
        {
            if (value != base.Name)
            {
                RaiseEvent();
            }

            base.Name = value;
        }
    }
}

如果你要这么做,为什么要使用自动属性?!

一个简单的属性已经做它早在1.0。我不认为这是有道理的复杂性增加了语言每一个特殊情况。你要么需要物业办普通存储/检索模型或需要比这更多。在后一种情况下,一个正常的属性都行。

您不能这样做,我害怕。这就是我开始写 MoXAML的电动玩具的原因之一,提供的能力自动转换成属性通知属性。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top