首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C#中是否有计算等价的剔除器?

在C#中是否有计算等价的剔除器?
EN

Stack Overflow用户
提问于 2017-04-14 15:00:25
回答 1查看 159关注 0票数 2

我经常使用knockout.js,我喜欢计算可观测性的概念。

计算可观测性定义为其他可观测值的函数的思想,它依赖于其内部使用的任何可观测变量。

这允许非常有趣的场景,在这种情况下,所有的因变量一旦发生影响其他计算变量的单个可观察的更改就会更新一次。

http://knockoutjs.com/documentation/computedObservables.html

问题:C#是否具有使用标准库或开源库的等价功能?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-04-15 07:57:36

回答:是的,有。

接口INotifyPropertyChanged正在这样做,它位于System.ComponentModel命名空间中。

此接口包含一个PropertyChanged事件,该事件将在更改属性时触发。

C# 4及以下示例

代码语言:javascript
复制
public class DataCS4 : INotifyPropertyChanged
{
    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion

    // Represent an Observable
    private int firstNumber;
    public int FirstNumber
    {
        get { return firstNumber; }
        set
        {
            if (value == firstNumber)
                return;

            this.firstNumber = value;
            OnPropertyChanged("FirstNumber");
            OnPropertyChanged("Sum");
        }
    }

    // Represent an Observable
    private int secondNumber;
    public int SecondNumber
    {
        get { return secondNumber; }
        set
        {
            if (value == secondNumber)
                return;

            this.secondNumber = value;
            OnPropertyChanged("SecondNumber");
            OnPropertyChanged("Sum");
        }
    }

    // Represent Computed
    public int Sum { get { return FirstNumber + SecondNumber; } }
}

这是两个整数求和的简单例子。

我们有FirstNumber属性,(我们可以认为它是可以观察到的)。

我们也有SecondNumber属性(我们可以认为它是可以观察到的。)

我们有Sum性质(我们可以认为它是Knockout计算出来的)。

现在,每当我们更改FirstNumberSecondNumber (通过调用它们对应的set函数)时,我们都会通知所有订阅者这些属性(这是通过调用OnPropertyChanged方法实现的)。

另外,我们正在为OnPropertyChanged属性调用Sum属性,以便通知该属性的订阅者该属性的值已经更改。

注意当使用WPF + MVVM模式时,这是非常常见的模式。

当使用C# 5.0C# 6.0__时,您可以从它们的新特性中获益,从而使代码变得更容易

C# 5.0示例

代码语言:javascript
复制
public class DataCS5 : INotifyPropertyChanged
{
    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion

    // Represent an Observable
    private int firstNumber;
    public int FirstNumber
    {
        get { return firstNumber; }
        set
        {
            if (value == firstNumber)
                return;

            this.firstNumber = value;
            OnPropertyChanged();
            OnPropertyChanged("Sum");
        }
    }

    // Represent an Observable
    private int secondNumber;
    public int SecondNumber
    {
        get { return secondNumber; }
        set
        {
            if (value == secondNumber)
                return;

            this.secondNumber = value;
            OnPropertyChanged();
            OnPropertyChanged("Sum");
        }
    }


    // Represent Computed
    public int Sum { get { return FirstNumber + SecondNumber; } }
}

这里有两个变化

  1. 因此,通过将该属性置于方法的参数之前,编译器将自动知道调用此方法的属性的名称,而无需手动传递属性名,因此我们可以编写以下语句。
  2. 表示第二次修改的OnPropertyChanged();

注意:CallerMemberName属性存在于System.Runtime.CompilerServices命名空间中。

C# 6.0示例

使用C# 6.0可以简化OnPropertyChanged方法的实现。

代码语言:javascript
复制
public class DataCS6 : INotifyPropertyChanged
{
    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    // C# 6.0
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion

    // Represent an Observable
    private int firstNumber;
    public int FirstNumber
    {
        get { return firstNumber; }
        set
        {
            if (value == firstNumber)
                return;

            this.firstNumber = value;
            OnPropertyChanged();
            OnPropertyChanged("Sum");
        }
    }

    // Represent an Observable
    private int secondNumber;
    public int SecondNumber
    {
        get { return secondNumber; }
        set
        {
            if (value == secondNumber)
                return;

            this.secondNumber = value;
            OnPropertyChanged();
            OnPropertyChanged("Sum");
        }
    }

    // Represent Computed
    public int Sum => FirstNumber + SecondNumber;
}

参考文献

更新

对以下评论的答复:

有意思的!但是在这里,您必须自己管理依赖项。您必须触发一个更改为Sum的属性。在淘汰赛中,它自己计算出哪些属性将触发在计算结果上更改的属性。有什么办法吗?

我想你可以有两个选择(至少)

  1. 基于PropertyChanged的GitHub库。 该图书馆的描述如下: 在编译时将INotifyPropertyChanged代码注入属性

以下是从努基特下载库后的新代码

PropertyChanged.ImplementPropertyChanged公共类数据{ public int FirstNumber { get;set;} public int SecondNumber { get;set;} public int Sum => SecondNumber + FirstNumber;}

2.PostSharp库

干杯!

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43414112

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档