gpt4 book ai didi

c# - c# 模型的 HasChanged 方法

转载 作者:太空宇宙 更新时间:2023-11-03 14:50:08 26 4
gpt4 key购买 nike

我正在寻找一种解决方案,如果属性已更改,我可以询问模型。但我想防止为所有模型及其所有属性编写自己的设置方法。

我想用它来自动生成基于模型的更新查询并更改属性。但是,如果我的模型有一个 bool 属性 Test,默认情况下为 false,那么我无法区分该值是来自请求负载还是默认值.

我已经看到了 INotifyPropertyChanged 实现,但我还必须为所有属性编写一个 setter。

public class Main
{
public static void main()
{
var person = new Person();

Console.WriteLine(person.HasChanged("Firstname")); // false
Console.WriteLine(person.HasChanged("Lastname")); // false
Console.WriteLine(person.HasChanged("LikesChocolate")); // false

person.Firstname = "HisFirstname";
person.LikesChocolate = true;

Console.WriteLine(person.HasChanged("Firstname")); // true
Console.WriteLine(person.HasChanged("Lastname")); // false
Console.WriteLine(person.HasChanged("LikesChocolate")); // true
}
}

public class Person : BaseModel
{
public string Firstname { get; set; }
public string Lastname { get; set; }
public bool LikesChocolate { get; set; }
}

public class BaseModel
{
public bool HasChanged(string propertyName)
{
// ...
}
}

最佳答案

我可能会通过他们的 INotifyPropertyChanged 模式重用 WPF 的想法,并根据当前需要稍微简化它。但是,它只能部分解决问题,因为您仍然需要编写 setter。但至少,您不需要单独管理每个属性。

所以,解决方案将是这样的:

void Main()
{
var person = new Person();

Console.WriteLine(person.HasChanged(nameof(Person.FirstName))); // false
Console.WriteLine(person.HasChanged(nameof(Person.LastName))); // false
Console.WriteLine(person.HasChanged(nameof(Person.LikesChocolate))); // false

person.FirstName = "HisFirstname";
person.LikesChocolate = true;

Console.WriteLine(person.HasChanged(nameof(Person.FirstName))); // true
Console.WriteLine(person.HasChanged(nameof(Person.LastName))); // false
Console.WriteLine(person.HasChanged(nameof(Person.LikesChocolate))); // true
}

public class Person : ChangeTrackable
{
private string _firstName;
private string _lastName;
private bool _likesChocolate;

public string FirstName
{
get { return _firstName; }
set { SetProperty(ref _firstName, value); }
}

public string LastName
{
get { return _lastName; }
set { SetProperty(ref _lastName, value); }
}

public bool LikesChocolate
{
get { return _likesChocolate; }
set { SetProperty(ref _likesChocolate, value); }
}
}

public class ChangeTrackable
{
private ConcurrentDictionary<string, bool> _changes =
new ConcurrentDictionary<string, bool>();

public bool HasChanged(string propertyName)
{
return _changes.TryGetValue(propertyName, out var isChanged)
? isChanged : false;
}

public void ResetChanges()
{
_changes.Clear();
}

protected void SetProperty<T>(
ref T storage, T value, [CallerMemberName] string propertyName = "")
{
if (!Equals(storage, value))
{
_changes[propertyName] = true;
}
}
}

ChangeTrackable 跟踪属性是否已更改,并且在没有任何保证高性能的反射的情况下执行。请注意,对于此实现,如果您在构造对象后使用一些实际值初始化属性,则需要调用 ResetChanges。缺点是您需要用其支持字段编写每个属性并调用 SetProperty。另一方面,您决定要跟踪的内容,这在您的应用程序中将来会很方便。此外,我们不需要将属性编写为字符串(感谢编译时 CallerMemberNamenameof),这简化了重构。

关于c# - c# 模型的 HasChanged 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52099856/

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