回调函数和最佳实践

本文关键字:最佳 函数 回调 | 更新日期: 2023-09-27 18:12:32

更新:我措词错误。内部和外部的Latitude/Longitude成员都需要彼此更新,从而导致递归。外部成员由数据库上下文更新,而内部成员由UI更新。因此,来自数据库的任何更改都必须传播到UI,反之亦然。Coordinates类不能与UI分离,外部成员不能与数据库分离。

我想一个防止递归的标志是解决这个问题最简单的方法。

我有以下类:

class Coordinates
{
    public double Latitude { get; set; }
    public double Longitude { get; set; }
}
class Location
{
    public string Name { get; set; }
    public Coordinates Coordinates { get; set; }
    public double CoordinateLatitude
    {
        get { return (this.Coordinates.Latitude); }
        set { /* This member needs to get updated every time Location.Coordinates.Latitude gets updated. */ }
    }
    public double CoordinateLongitude
    {
        get { return (this.Coordinates.Latitude); }
        set { /* This member needs to get updated every time Location.Coordinates.Latitude gets updated. */ }
    }
}

成员CoordinateLatitudeCoordinateLongitude映射到Coordinates类。我想要达到的也是相反的效果。因此,当Coordinates类更新时,Location类的成员也应该更新。不要问我为什么代码的结构是这样的,因为我现在不能自由地修改它。

在整个项目中有很多代码设置了Coordinates类的成员:location.Coordinates.Latitude = 10.0D;等。由于Coordinates类(以及许多其他类)是轻量级数据结构,并且在许多地方被漫不经心地使用,因此我不想将它们与事件联系起来。

我的问题是,我怎么能有位置。坐标成员更新Location。CoordinateLatitude价值观?是否有一种标准的方法来设置这样的回调,而不需要IDisposable来清理(如在事件的情况下)?

回调函数和最佳实践

但是coordinatelatience会被更新
我测试了你的代码

Location myLoc = new Location();
myLoc.Coordinates = new Coordinates();
myLoc.Coordinates.Latitude = 10;
System.Diagnostics.Debug.WriteLine(myLoc.CoordinateLatitude.ToString());
myLoc.Coordinates.Latitude = 20;
System.Diagnostics.Debug.WriteLine(myLoc.CoordinateLatitude.ToString());

可能你想问的是为什么UI不更新

根本不清楚哪个是内部的,哪个是外部的,以及你在哪里得到递归。
他们不会(也不应该)互相更新。
它们只是引用同一个对象。

这对我有用。

class Coordinates
{
    public double Latitude { get; set; }
    public double Longitude { get; set; }
}
class Location : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
    public string Name { get; set; }
    private Coordinates coordinates = new Coordinates();
    public Coordinates Coordinates 
    {
        get { return coordinates; }
        set
        {
            if (coordinates == value) return;
            coordinates = value;
            NotifyPropertyChanged("Coordinates");
            NotifyPropertyChanged("CoordinateLatitude");
            NotifyPropertyChanged("CoordinateLongitude");
        }
    }
    public double CoordinateLatitude
    {
        get { return (this.Coordinates.Latitude); }
        set { this.Coordinates.Latitude = value; }
    }
    public double CoordinateLongitude
    {
        get { return (this.Coordinates.Longitude); }
        set { this.Coordinates.Longitude = value; }
    }
}

你的代码中有一个bug:

public double CoordinateLatitude
    {
        get { return (this.Coordinates.Latitude); }
        set { /* This member needs to get updated every time Location.Coordinates.Latitude gets updated. */ }
    }
    public double CoordinateLongitude
    {
        get { return (this.Coordinates.Latitude); }
        set { /* This member needs to get updated every time Location.Coordinates.Latitude gets updated. */ }
    }

CoordinateLongitude中的Latitude改为Longitude。另外,我不建议你把它们分开存放。由于它们通常对应于需要纬度和经度作为坐标的点,因此单独存储它们是没有意义的。这将只需要一个调用,您可以完全消除CoordinateLatitude/Longitude

话虽如此,你所要做的就是添加这些setter:

set { this.Coordinates.Latitude = value; }

set { this.Coordinates.Longitude = value; }

Coordinates是一个类,所以如果你改变它,任何使用相同实例的变量都会自动更新。假设我正确理解了你想要做的事情,你的集合可以是:

public double CoordinateLatitude
{
    get { return (this.Coordinates.Latitude); }
    set { this.Coordinates.Latitude = value; }
}
public double CoordinateLongitude
{
    get { return (this.Coordinates.Longitude); }
    set { this.Coordinates.Longitude = value;  }
}

编辑:如果Coordinates是一个结构体,则需要以不同的方式完成。这是由于this.Coordinates在这种情况下检索一个副本。

public double CoordinateLongitude
{
    get { return (this.Coordinates.Longitude); }
    set {
        Coordinate temp = this.Coordinates;
        temp.Longitude = value;
        this.Coordinates = temp;
    }
}

既然Coordinates已经是你在CoordinateLatitude中阅读的Location的属性,你已经完成了。从Location.Coordinate.Latitude读取与从Location.CoordinateLatitude读取相同。

public Coordinates Coordinates { get; set; }
public double CoordinateLatitude
{
  get { return (this.Coordinates.Latitude); }
  set { this.Coordinates.Latitude = value;}
}

在你的setter中,你可以更新它来设置Location.Coordinate.Latitude的值,或者只是删除设置,使其成为只读属性。