生成空对象 - 使用空属性/子类的空类C#

9

我有两个类:

public class HumanProperties { int prop1; int prop2; string name;}

public class Human{int age; HumanProperties properties;}

现在,如果我想创建一个 Human 的新实例,我必须执行 Human person = new Human();。但是当我尝试像这样访问 person.properties.prop1=1; 时,由于我还要创建新的属性,因此在属性上出现 nullRefrence 错误。 我必须像这样创建:

Human person = new Human();
person.properties = new HumanProperties();

现在我可以访问这个 person.properties.prop1=1;

这只是一个小例子,但是我有一个从xsd生成的巨大类,而我没有时间手动生成所有子类。有没有办法通过编程方式完成它或者有没有相关的代码生成器?

或者我能循环遍历类并为每个属性创建新类,并将其加入到父类中吗?

谢谢!


值得注意的是,你的类没有属性,只有公共字段。它们可能应该改为属性,但目前还没有这样做。 - Servy
4个回答

9

我认为没有传统的方法可以实现您要求的操作,因为类的默认类型是null。但是,您可以使用反射递归地遍历属性,查找具有无参数构造函数并初始化它们的公共属性。以下是一些可能有效的示例代码(未经测试):

void InitProperties(object obj)
{
    foreach (var prop in obj.GetType()
        .GetProperties(BindingFlags.Public | BindingFlags.Instance)
        .Where(p => p.CanWrite))
    {
        var type = prop.PropertyType;
        var constr = type.GetConstructor(Type.EmptyTypes); //find paramless const
        if (type.IsClass && constr != null)
        {
            var propInst = Activator.CreateInstance(type);
            prop.SetValue(obj, propInst, null);
            InitProperties(propInst);
        }
    }
}

然后你可以这样使用它:
var human = new Human();
InitProperties(human); 

5
我建议您使用构造函数:
public class Human
{
  public Human()
  {
     Properties = new HumanProperties();
  }

  public int Age {get; set;} 
  public HumanProperties Properties {get; set;}
}

这是问题示例中最明显的解决方案。但是,我认为 OP 想要初始化一个深层嵌套类属性,而不仅仅是单个级别。想象一下 HumanPropertiesInnerProperties,而那些又有 DetailedInnerProperties 等等。如果我正确理解了问题,OP 希望在构造函数中将所有这些都初始化为“非空”,而不必手动为每个创建 new Instance() - Eren Ersönmez
1
在我看来,每个类都应负责实例化自己的属性。我认为最好在该类的构造函数中完成此操作,无论类层次结构或嵌套属性如何。 - Jens Kloster
我同意您的观点。然而,如果该类设计用于通用目的,则可能希望或不希望初始化属性-也许将它们保留为“null”最佳。如果该用户有一个特殊的用例需要以这种方式进行初始化,我不会通过更改构造函数来要求所有用户遵守此规定。 - Eren Ersönmez

1
您可以将您的类声明更改为以下内容:

public class Human
{
    int age;
    HumanProperties properties = new HumanProperties();
}

0

.NET 使用属性。

您可以使用 Visual Studio 快捷键:Ctrl+r,Ctrl+e 来自动生成属性。

试试这个:

public class HumanProperties
{
    public int Prop1
    {
        get { return _prop1; }
        set { _prop1 = value; }
    }
    private int _prop1 = 0;

    public int Prop2
    {
        get { return _prop2; }
        set { _prop2 = value; }
    }
    private int _prop2;

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }
    private string _name = String.Empty;
}

public class Human
{
    public int Age
    {
        get { return _age; }
        set { _age = value; }
    }
    private int _age = 0;

    public HumanProperties Properties
    {
        get { return _properties; }
        set { _properties = value; }
    }
    private HumanProperties _properties = new HumanProperties();
}

为什么要手动创建属性,当你可以使用自动属性呢? - Servy
@Servy 如果您手动创建它们,可以指定默认值。在这种情况下,您可以确保 HumanProperties _properties 不为 null。 - rhughes
你可以在自动属性的构造函数中用更少的代码实现此操作。 - Servy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接