如果我有一个名为MyObject
的类,我想向其传递可变数量的参数。如何创建make这个?有时只使用名称,有时使用所有内容。
我正在使用c#和4.0
MyObject
int Id
string name
datetime creationdate
int createbyid
int modifiedbyid
datetime modifieddate
答案 0 :(得分:3)
使用object initialization syntax可能最简单。
MyObject obj = new MyObject() { Id = 27, Name = "Daniel" };
如果您需要某些东西,请使用构造函数参数。
答案 1 :(得分:0)
您可以为要覆盖的每个方案创建不同的构造函数。
public class MyClass
{
public MyClass(string name)
{
}
public MyClass(string name, DateTime creationDate)
{
}
}
这样可以防止您的对象被构造为错误的初始状态。
答案 2 :(得分:0)
这个答案可能会让一些人感到畏缩,但有些人会喜欢它,因为它会给你object initialization syntax的好处 - 完全灵活 - 而且还允许你添加验证器,将参数分配给私人或readonly字段,并执行对象初始化语法无法实现的其他运行时检查。
摘要:传递一个包含所需命名参数的匿名对象,然后使用一些反射读出它们。
首先,创建此扩展方法:
static class ObjectExtensions
{
//Helper method for reading the properties from an anonymous class
public static T Peek<T>(this object source, string propertyName)
{
var prop = source.GetType().GetProperty(propertyName, typeof(T));
return (prop == null) ? default(T) : (T)prop.GetValue(source);
}
}
然后,使用单个构造函数参数定义您的类,键入为object
。编写代码以使用我们刚写的Peek
方法读取值:
class MyClass
{
private readonly string _name;
private readonly int _id;
private readonly double _optional;
public MyClass(object o)
{
_name = o.Peek<string>("Name");
_id = o.Peek<int>("ID");
_optional = o.Peek<double>("Optional");
}
public void ProveThatItWorked()
{
Console.WriteLine(String.Format("ID = '{0}' Name = '{1}' Optional='{2}'", _id, _name, _optional));
}
}
现在,您可以使用匿名类型实例化MyClass
,使用您想要的任何参数,例如:
MyClass c = new MyClass(new { Name = "My Name", ID = 17 });
c.ProveThatItWorked();
使用此技术,您可以在该匿名对象中传递任意数量的命名参数,只要您有Peek
个语句来读取它们即可。如果参数未包含在匿名类型中,它将仅作为该参数的数据类型的默认值返回。如果您包含一个未使用的参数,它将被忽略。
如果需要,您甚至可以从LINQ查询中传递一行,使其对域类型对象非常强大:
var list = from t in db.table
select new { ID = t.SomeIdentifier, Name = t.SomeName };
foreach (var i in list) {
var c = new MyClass(i);
c.ProveThatItWorked();
}
使用对象初始化语法尝试 。
注意事项:
object
上定义扩展方法通常是不受欢迎的。从来没有亲自打扰过我。string
,其中int
是预期的。这将真的打扰很多人,虽然它完全是Javascript世界或其他duck-typed语言的常态。但是如果您想要编译时检查,只需定义自己的类而不是使用匿名类,然后传递它。