Javascript 在C#中是否存在敲除JS计算的等价物?

Javascript 在C#中是否存在敲除JS计算的等价物?,javascript,c#,knockout.js,Javascript,C#,Knockout.js,我使用了很多,我喜欢计算可观测的概念。一个计算可观测的概念被定义为其他可观测的函数,它依赖于它内部使用的任何可观测变量。这允许出现非常有趣的场景,其中所有因变量在单个可观测变化时更新这会影响其他计算变量 问题:C#是否有使用标准库或开源库的等价物?答案:是的,有。 接口正在这样做,它位于System.ComponentModel命名空间中 此接口包含一个事件,该事件将在属性更改时触发 C#4及以下示例 public class DataCS4 : INotifyPropertyChanged

我使用了很多,我喜欢计算可观测的概念。
一个计算可观测的概念被定义为其他可观测的函数,它依赖于它内部使用的任何可观测变量。
这允许出现非常有趣的场景,其中所有因变量在单个可观测变化时更新这会影响其他计算变量


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

答案:是的,有。

接口正在这样做,它位于
System.ComponentModel
命名空间中
此接口包含一个事件,该事件将在属性更改时触发

C#4及以下示例

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
(通过调用相应的set函数),我们都会通知所有订阅者这些属性(通过调用
OnPropertyChanged
方法完成)

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

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

当使用C#5.0C#6.0时,您可以从它们的新功能中获益,使代码更简单

C#5.0示例

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; } }
}
这里有两个变化

  • protected virtual void OnPropertyChanged([CallerMemberName]string propertyName=null)
    ,因此通过将此属性放在方法的参数之前,编译器将自动知道调用此方法的属性的名称,而无需手动传递属性名称,因此我们可以编写以下语句
  • OnPropertyChanged()表示第二次修改
  • 注意:
    CallerMemberName
    属性存在于
    System.Runtime.CompilerServices
    命名空间中

    C#6.0示例

    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; } }
    }
    
    使用C#6.0,我们可以简化
    OnPropertyChanged
    方法的实现

    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更改的属性。在击倒中,它自己计算出哪些属性将触发在计算机上更改的属性。有办法吗

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

  • .
    此库的说明如下:

    在编译时将INotifyPropertyChanged代码注入属性

    以下是从下载库后的新代码

    二,



  • 干杯

    var compute=()=>num1+num2?从本质上讲,只有一种内置类型/接口可以确定这种ioc的方向,如observableCollection、INotifyPropertyChanged等。。。但据我所知,没有什么是这样的。但这听起来像是AOP模式(Postsharp、NConcern、Fody、Castle等)的一种特殊情况,很有趣!但在这里,您必须自己管理您的依赖关系。您必须触发为Sum更改的属性。在击倒中,它自己计算出哪些属性将触发在计算机上更改的属性。有什么办法吗?你是对的。你必须以这种方式管理你自己。事实上,我没有其他方法可以自动完成,但也许我会serach@EtienneT我根据你的评论更新了我的答案。