2012-04-20 90 views
0

改写了这个问题。向下滚动以获取原始图片属性更改通知属性

好的,也许我应该给你整张照片。我有很多类,看起来是这样的:

public class Movement : Component 
{ 
    private Vector3 linearVelocity; 
    public Vector3 LinearVelocity 
    { 
     get 
     { 
      return linearVelocity; 
     } 
     set 
     { 
      if (value != linearVelocity) 
      { 
       linearVelocity = value; 
       ComponentChangedEvent<Movement>.Invoke(this, "LinearVelocity"); 
      } 
     } 
    } 

    // other properties (e.g. AngularVelocity), which are declared exactly 
    // the same way as above 
} 

还有一些类称为变换,网格,对撞机,外观等都是从Component衍生的所有都没有,但被上述声明的属性。这里重要的是调用ComponentChangedEvent。一切都很完美,但我正在寻找一种方法,我不必一次又一次地为每个属性重写相同的逻辑。

我看了一下here并喜欢使用泛型属性的想法。我想出什么样的主意看起来像这样:

public class ComponentProperty<TValue, TOwner> 
{ 
    private TValue _value; 

    public TValue Value 
    { 
     get 
     { 
      return _value; 
     } 
     set 
     { 
      if (!EqualityComparer<TValue>.Default.Equals(_value, value)) 
      { 
       _value = value; 
       ComponentChangedEvent<TOwner>.Invoke(
        /*get instance of the class which declares value (e.g. Movement instance)*/, 
        /*get name of property where value comes from (e.g. "LinearVelocity") */); 
      } 
     } 
    } 

    public static implicit operator TValue(ComponentProperty<TValue, TOwner> value) 
    { 
     return value.Value; 
    } 

    public static implicit operator ComponentProperty<TValue, TOwner>(TValue value) 
    { 
     return new ComponentProperty<TValue, TOwner> { Value = value }; 
    } 
} 

然后我会用这样的:

public class Movement : Component 
{ 
    public ComponentProperty<Vector3, Movement> LinearVelocity { get; set; } 
    public ComponentProperty<Vector3, Movement> AngularVelocity { get; set; } 
} 

但我不能够得到实例,其中LinearVelocity来自也不是它的名字为字符串。所以我的问题是,如果所有这一切都是可能的... ...

但似乎我没有选择,除了继续按照我的方式,手动为每个属性编写此逻辑。

原题:

物业

获取声明类的实例我有一个属性的类:

public class Foo 
{ 
    public int Bar { get; set; } 
} 

在另一个方面,我有这样的事情:

Foo fooInstance = new Foo(); 
DoSomething(fooInstance.Bar); 

然后,在DoSomething我需要得到fooInstance除了parameter。从上下文来看,假设没有任何整数被传递到DoSomething,而只是整数的公有属性。

public void DoSomething(int parameter) 
{ 
    // need to use fooInstance here as well, 
    // and no, it is not possible to just pass it in as another parameter 
} 

这可能吗?使用反射,或者属性Bar上的自定义属性?

+4

你将不得不重新考虑你的设计。这不可能。 – BrokenGlass 2012-04-20 16:38:35

+0

我不明白你在问什么......为什么你不能给'Foo'作为参数? – log0 2012-04-20 16:40:30

+0

为什么你不能将它作为另一个参数传入? – 2012-04-20 16:43:23

回答

2

有几种方法来处理实施INotifyPropertyChanged。你做的事情几乎是一样的,除非你不以不同的方式实现接口并提升事件。但所有的解决方案也适用于你。

  1. 像你这样,调用带字符串参数的方法:OnPropertyChanged("Property")
  2. 调用使用属性的lambda的方法:OnPropertyChanged(() => Property)。这样做的好处是编译时检查错误和重构友好。
  3. 使用caller information注入属性的名称:OnPropertyChanged()。这将在C#5中工作。
  4. 使用类似Castle DynamicProxy的东西在运行时创建派生类,它将为您调用方法。这意味着您需要制作属性virtual,并且您只需通过Castle创建该类的实例。
  5. 使用AOP框架在编译后修改属性的代码以调用方法。
+0

谢谢,我会看看到这些。实现INotifyPropertyChanged也应该这样做。来电信息(和其他C#5的东西)看起来很有趣,但这是未来。 – christoph 2012-04-21 11:35:43

0

没有办法从parameter得到fooInstanceparameter是按值传递,而只是fooInstance.Bar值的副本,它不再有什么关系fooInstance

话虽这么说,明显的解决方案是写DoSomething这样

public void DoSomething(Foo parameter) 
{ 
    // need to use fooInstance here as well, 
    // and no, it is not possible to just pass it in as another parameter 
} 
3

为什么你想只是一个属性发送到DoSomething的,把它整个对象:),所以它会成为,然后

DoSomething(fooInstance); 

你的函数将接受对象,而不是参数。您可以使用此函数的重载来确保旧代码不会中断。

0

属性只是一个字段,它返回对堆上某个对象(即其地址)的引用。如果属性不是引用类型,则返回对象的值。

所以,当你做这样的事情

DoSomething(fooInstance.Bar); 

你只是路过对象酒吧的地址的方法。

如果Bar是引用类型(即类)。想象一下,Mr.Foo的Mr.Bar地址(462,马里恩县,印第安纳州)。 CLR夫人向Mr.Foo问Mr.Bar的地址。然后告诉这个地址给需要Mr.Bar地址的人。有人会知道,CLR问Foo Bar的地址?他只收到印第安纳州马里恩县462的地址

在值对象(int,double,structs等)的情况下,Mr.Foo有一个很酷的mp3轨道名为Bar。 CLR夫人创建了该mp3歌曲的副本并将其发送给某人。如何有人会知道,他的MP3轨道酒吧是Mr.Foo的轨道副本?

所以,如果你希望有人知道Mr.Foo,你需要Mr.Foo的地址传递给他:

DoSomething(fooInstance); 

有了这个地址有人可以访问Mr.Foo并且询问他关于Mr.Bar的地址,或创建他的MP3曲目的副本:)

+0

已经回答了其实参数更像是一个函数;有一个getter和setter返回/设置属性的本地值。如果这个属性是一个引用类型,那么它只会传递一个新的对象引用,并且引用将是内存中的同一个对象。由于这是一个值类型,它将会传回一个新值的副本。 – 2012-04-20 17:04:21

+0

@ShawnL,我知道,那属性实际上是GET_NAME和set_Name功能:)只是想lazyberezovsky简化 – 2012-04-20 17:08:39

+0

谢谢,丰富多彩的交代:) – christoph 2012-04-21 11:28:58