调用具有无限参数的构造函数

时间:2017-04-11 01:04:52

标签: c# constructor

如果我有一个名为MyObject的类,我想向其传递可变数量的参数。如何创建make这个?有时只使用名称,有时使用所有内容。

我正在使用c#和4.0

MyObject

  int Id
  string name
  datetime creationdate
  int createbyid
  int modifiedbyid
  datetime modifieddate

3 个答案:

答案 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语言的常态。但是如果您想要编译时检查,只需定义自己的类而不是使用匿名类,然后传递它。