9

I have two classes:

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

public class Human{int age; HumanProperties properties;}

Now if i want to create new instance of Human, i have to do Human person = new Human(); But when i try to access like person.properties.prop1=1; then i have nullRefrence at properties, beacuse i have to make new properties too. I have to make like that:

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

and now i can access this person.properties.prop1=1;

This was small example, but i have huge class generated from xsd and i dont have so much time for generating manually this "person" class with all its subclasses. Is there some way how to do it programmatically or is there some generator for that?

Or can i loop through class and make for every property new class typeof property and join it to parent class?

Thanks!

Muno
  • 749
  • 2
  • 9
  • 19
  • It's worth noting that your class doesn't have properties, it just has public fields. They probably *should* be properties instead, but they are not currently. – Servy Feb 25 '13 at 07:22

4 Answers4

9

I don't thing there is a conventional way to do what you're asking for as the default type for classes is null. However, you can use reflection to recursively loop through the properties, looking for public properties with parameter-less constructors and initialize them. Something like this should work (untested):

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);
        }
    }
}

Then you can use this like so:

var human = new Human();
InitProperties(human); 
Eren Ersönmez
  • 38,383
  • 7
  • 71
  • 92
5

I would suggest you use the constructor:

public class Human
{
  public Human()
  {
     Properties = new HumanProperties();
  }

  public int Age {get; set;} 
  public HumanProperties Properties {get; set;}
}
Jens Kloster
  • 11,099
  • 5
  • 40
  • 54
  • This is the most obvious solution for the example in the question. However, I think the OP is asking to initialize a deep hierarchy of nested class properties, not just a single level. Imagine `HumanProperties` have `InnerProperties`, and those have `DetailedInnerProperties`, etc. If I understand the question correctly, the OP wants to initialize all those to be "not null" without manually creating a `new Instance()` for each of them in the constructor. – Eren Ersönmez Feb 25 '13 at 07:37
  • 1
    In my opinion - each class is responsible for instantiate its own properties. And i belivet it is best done in the constructor of that class. Regardless of class hierarchy or nested properties. – Jens Kloster Feb 25 '13 at 07:43
  • I agree with you. However, if the class is designed for general use, you may or may not want to initialize the properties -- maybe it's best you leave them as `null`. And if this user has a one-off use case where he wants to init this way, I wouldn't dictate that to all the users by changing the constructors. – Eren Ersönmez Feb 25 '13 at 07:59
1

You can change your class declaration to this:

public class Human
{
    int age;
    HumanProperties properties = new HumanProperties();
}
MarcinJuraszek
  • 124,003
  • 15
  • 196
  • 263
0

.NET makes use of properties.

You can use the Visual Studio keyboard shortcut: Ctrl+r, Ctrl+e to auto generate the property.

Try this:

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();
}
rhughes
  • 9,257
  • 11
  • 59
  • 87
  • Why bother creating properties manually like that when you can just use auto properties? – Servy Feb 25 '13 at 07:21
  • @Servy if you create them manually, you can specify the default values. In this case, you can ensure that HumanProperties _properties is not null. – rhughes Feb 25 '13 at 07:29
  • Which you can do in a constructor for an auto property in far less code. – Servy Feb 25 '13 at 14:37