gpt4 book ai didi

c# - 使用反射初始化对象的自动属性——有什么注意事项吗?

转载 作者:太空宇宙 更新时间:2023-11-03 13:28:44 25 4
gpt4 key购买 nike

我最近写了两个类和一个接口(interface)来实现 this question of mine 的答案。 .

第一个类是Notifier泛型类:

public interface INotifier { }
public class Notifier<T> : Observable,INotifier where T:new()
{
public Notifier()
{
V = new T();
}
private T _ValueBacker;
public T V
{
get { return _ValueBacker; }
set
{
_ValueBacker = value;
OnPropertyChanged(() => V);
}
}
}

这里的Observable基类只是一个实现了INotifyPropertyChanged并定义了一个OnPropertyChanged方法的类。

感谢该类(class),我现在可以像这样定义 Silverlight/WPF ViewModel:

public class Person : ViewModelBase
{
Notifier<string> Name {get;set;}
Notifier<string> Surname {get;set;}
Notifier<int> Age {get;set;}
}

代替:

public class Person : Observable
{
private string _Name;
public string Name
{
get
{
return _Name;
}
set
{
_Name=value;
OnPropertyChanger(()=>Name);
}
}
privaate string _Surname;
public string Surname
{
get
{
return _Surname;
}
set
{
_Surname=value;
OnPropertyChanger(()=>Surname);
}
}
private int _Age;
public int Age
{
get
{
return _Age;
}
set
{
_Age=value;
OnPropertyChanger(()=>Age);
}
}
}

如您所见,新代码更加简洁,并且更不容易出现编码错误(或打字错误)。我在我的 XAML 中所要做的就是绑定(bind)到“MyPerson.V”而不是“MyPerson”。但是,由于没有任何方法可以为自动属性实现初始化器,我不得不在构造函数中初始化每个属性。在某些情况下,我跳过了初始化程序,这导致了一些运行时错误。因此,为了解决这个问题,在 ViewModelBase 类的构造函数中,我添加了这个循环:

    public ViewModelBase()
{
foreach(var notifierProperty in this.GetType().GetProperties().Where(c=>c.PropertyType.GetInterfaces().Any(d=>d==typeof(INotifier))))
{
notifierProperty.SetValue(this, notifierProperty.PropertyType.GetConstructor(System.Type.EmptyTypes).Invoke(null), null);
}
}

这样做的目的是,每当您实例化 ViewModelBase 派生类时,构造函数都会循环遍历属性,并为每个 Notifier 类型的属性调用构造函数。

这是邪恶的吗?以这种方式使用反射会在将来再次困扰我吗?有什么我应该注意的性能影响吗?

最佳答案

我觉得还行。我有一些信息要补充:

  1. 您可以通过调用 Activator.Create(myType) 来创建具有普通构造函数的类型,这意味着您不必获取构造函数。
  2. 我相信至少对于 Silverlight,所有使用您的 hack 初始化的属性都需要公开。
  3. 有一个图书馆叫 ReactiveProperty ,它定义了一个类 ReactiveProperty<T>与您的 Notifier<T> 非常相似.

您将绑定(bind)它的 Value属性:

public class ReactiveProperty<T> : IObservable<T>, IDisposable, INotifyPropertyChanged, IReactiveProperty, INotifyDataErrorInfo
{
public T Value
{
get { return latestValue; }
set { anotherTrigger.OnNext(value); }
}

// ...
}

setter 中的调用最终导致对 INotifyPropertyChanged.PropertyChanged 的相应调用.

ReactiveProperty<T>也是 reactive extensions 意义上的可观察对象,库依赖于它。除此之外,作者基本上做了你所做的,但没有在构造函数中进行初始化 hack。

关于c# - 使用反射初始化对象的自动属性——有什么注意事项吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21385303/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com