需求
假如有这么一个需求,一个对象Person
内的属性设置外包给了另外一个类Options
,
而要设这个Person
对象的属性,就必须传一个Options
实例,
但又不能每个属性重新设一遍,只设要修改的属性。
- 基础代码
public class Options
{
public string Name { get; set; } = "";
public int Age { get; set; } = 0;
public string Gerder { get; set; } = "";
}
public class Person
{
public void SetOptions(Options options)
{
// 思考一下这里的实现方式
}
private Options myOpts = new Options();
}
- 调用代码
var p = new Person();
var opts = new Options()
{
Name = "Hepburn",
Age = 18,
Gerder = "Female"
};
p.SetOptions(opts);
/*
* p
* |_Name: Hepburn
* |_Age: 18
* |_Gender: Female
*
p.SetOptions(new Options() { Age = 19 });
* ↓↓↓
*
* p
* |_Name: Hepburn
* |_Age: 19
* |_Gender: Female
*
*/
p.SetOptions(new Options() { Age = 19 });
- 答案区
↓
↓
↓
↓
↓
↓
↓
↓
↓
public void SetOptions(Options options)
{
foreach (var p in options.GetType().GetProperties())
{
if(!p.CanWrite) continue;
var value = p.GetValue(options);
var valDefault = p.GetValue(new Options());
if(value != valDefault)
{
p.SetValue(myOpts, value);
}
}
}
这样,任何有指定值的时候都会被设上,同时,要求默认值都是没有意义的,比如 -1(负一),null 等,因为,设过一次之后,通过这种方法就再也改不回默认值了。