这是一个具有三个属性的对象:
public class myClass
{
public int score { get; set; }
public string name { get; set; }
public bool isAlive { get; set; }
}
在创建此类的实例后,在某些地方,我将更改该实例的两个或三个属性,如下所示:
targetInstance.score = 1;
targetInstance.name = "John";
targetInstance.isAlive = true;
有什么方法可以一次使用targetInstance
,然后以某种方式使用一些方括号来设置属性(例如初始化),类似于以下内容:
targetInstance = { score = 1, name = "John" }
注意:也许您建议使用一种方法来接收这些值并更改属性,但是在属性太多的情况下不适用。
答案 0 :(得分:5)
您可以编写带有命名默认参数的方法,并使用命名参数仅更新所需的参数。
例如:
public class myClass
{
public int score { get; set; }
public string name { get; set; }
public bool isAlive { get; set; }
public void Set(int score = -1, string name = null, bool? isAlive = null)
{
if (score != -1) this.score = score;
if (name != null) this.name = name;
if (isAlive.HasValue) this.isAlive = isAlive.Value;
}
}
您可以这样称呼它:
var o = new myClass();
o.Set(name: "Hello");
或
var o = new myClass();
o.Set(name: "Hello", isValid: false);
或
var o = new myClass();
o.Set(score: 100, isValid: false);
您可以创建一组可链接的“设置方法”,如下所示:
public class myClass
{
public int score { get; set; }
public string name { get; set; }
public bool isAlive { get; set; }
public myClass SetScore(int score)
{
this.score = score;
return this;
}
public myClass SetName(string name)
{
this.name = name;
return this;
}
public myClass SetIsAlive(bool isAlive)
{
this.isAlive = isAlive;
return this;
}
}
然后像这样使用它:
var o = new myClass();
o.SetName("Donald").SetIsAlive(true);
或者这样:
var o = new myClass()
.SetName("Bob")
.SetScore(0)
.SetIsAlive(true);
答案 1 :(得分:4)
最接近的是使用C#7 tuples解构语法:
(targetInstance.score, targetInstance.name, targetInstance.isAlive) = (1, "John", true);
尽管它仍然需要重复目标变量名,所以Daniel Hilgarth的答案是正确的。
答案 2 :(得分:3)
您正在寻找VB中With
关键字的等效项。
在C#中,没有任何内容。
答案 3 :(得分:1)
您可以将复制构造函数与对象初始化结合使用,当您要修改旧对象时可以新建一个全新的对象,也可以用新对象覆盖旧对象。像这样:
public class Person
{
public Person() // this is your default constructor
{
}
public Person(Person originalPerson) // this is your copy constructor
{
Name = originalPerson.Name;
Surname = originalPerson.Surname;
Address = originalPerson.Address;
Age = originalPerson.Age;
}
public string Name;
public string Surname;
public string Address;
public int Age;
}
public class Program
{
static void Main(string[] args)
{
// create object with whatever properties you like
var person1 = new Person
{
Name = "Max", Surname = "Mustermann", Age = 30,
};
// now rewrite the old object with the old properties and modify
// any properties you like using object initialization
person1 = new Person(person1)
{
Address = "Main Street 1",
Age = 32,
};
// now person1 has the Name, Surname from 1st assignment
// plus Address and Age from 2nd assignment (Age = 32)
}
}
答案 4 :(得分:1)
作为一种选择,您可以创建一个With
扩展方法:
public static class WithExtension
{
public static void With<T>(this T o, Action<T> values)
{
values?.Invoke(o);
}
}
然后以这种方式使用它:
person.With(p=>{
p.Id = 1;
p.Name = "Someone";
p.BirthDate = DateTime.Now;
});
另一个选择:
public static class WithExtension
{
public static void With(this object o, object values)
{
var props = TypeDescriptor.GetProperties(values);
var sourceProps = TypeDescriptor.GetProperties(o);
foreach (PropertyDescriptor p in props)
{
sourceProps[p.Name].SetValue(o, p.GetValue(values));
}
}
}
并像这样使用它:
person.With(new {Id = 1, Name = "Someone", BirthDate = DateTime.Now});
但是请注意,您依赖类型描述(或选择反射),并且只能在运行时发现属性名称中的错误。
答案 5 :(得分:1)
您可以使用Reflection
(在类代码中添加using System.Reflection;
)并将适当的方法添加到myClass
:
public void SetProperties(params object[] args)
{
for (int i = 0; i < args.Count(); i += 2)
{
PropertyInfo myProp = this.GetType().GetProperty(args[i].ToString());
myProp.SetValue(this, args[i + 1]);
}
}
您可以在代码中使用的如下:
targetInstance.SetProperties("score", 1, "name", "John", "isAlive", true);
targetInstance.SetProperties("isAlive", true, "score", 1);
targetInstance.SetProperties("name", "John", "isAlive", true);
以此类推...
您可能希望使用Try / Catch块增强SetProperties()
,以检查拼写错误的属性名称或值类型