回调函数和最佳实践

时间:2013-05-06 17:26:25

标签: c# .net events delegates callback

更新:我说错了这个问题。内部和外部纬度/经度成员都需要相互更新,从而导致递归。外部成员由数据库上下文更新,而内部成员由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.Coordinates成员更新Location.CoordinateLatitude值?是否有标准的方法来设置这样的回调而不需要IDisposable进行清理(如事件的情况)?

4 个答案:

答案 0 :(得分:1)

但是CoordinateLatitude确实会更新 我测试了你的代码

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

您可能会问的是为什么用户界面不会更新

根本不清楚哪个是内在的,哪个是外在的,以及你正在重新进行的地方 他们不会(不应该)相互更新 他们都只引用同一个对象。

这对我有用。

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

答案 1 :(得分:0)

您的代码中存在错误:

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. */ }
    }

Latitude中的CoordinateLongitude更改为Longitude。此外,我不建议您单独存储这些。由于它们通常对应于需要坐标的纬度和经度的点,因此将它们独立存储是没有意义的。这只需要一个电话,您可以完全取消CoordinateLatitude/Longitude

话虽这么说,你所要做的就是添加这些二传手:

set { this.Coordinates.Latitude = value; }

set { this.Coordinates.Longitude = value; }

答案 2 :(得分:0)

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

答案 3 :(得分:0)

由于Coordinates已经是Location的{​​{1}}属性,因此您已经完成了CoordinateLatitude。从Location.Coordinate.Latitude读取与从Location.CoordinateLatitude读取相同。

public Coordinates Coordinates { get; set; }

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

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