2

I'm trying to write a NullObject creation method, where I pass in a class name that implements an ICreateEmptyInstance interface (that is empty) and it walks it's properties looking for other classes that implement ICreateEmptyInstance and will create "Null" instances of those.

public interface ICreateEmptyInstance { }

public static class NullObject
{
    public static T Create<T>() where T : ICreateEmptyInstance, new()
    {
        var instance = new T();

        var properties = typeof(T).GetProperties();
        foreach (var property in properties.Where(property => typeof(ICreateEmptyInstance).IsAssignableFrom(property.PropertyType)))
        {
            var propertyInstance = NullObject.Create<property.PropertyType>();
            property.SetValue(instance, propertyInstance);
        }

        return instance;
    }
}

I should be able to call it with this

var myEmptyClass = NullObject.Create<MyClass>();

Where I'm having issues is inside of the foreach loop, with this line

var propertyInstance = NullObject.Create<property.PropertyType>();

...obviously that doesn't work, but how can I accomplish creating a "null object" to assign to the instance I'm currently creating.

EDIT: And what about generics?? I'd like empty instances created

  foreach (var property in properties.Where(property => property.GetType().IsGenericType))
  {
       var propertyInstance = Enumerable.Empty<>(); //TODO: how do I get the type for here?
       property.SetValue(instance, propertyInstance);
  }
CaffGeek
  • 21,856
  • 17
  • 100
  • 184
  • possible duplicate of [Get a new object instance from a Type](http://stackoverflow.com/questions/752/get-a-new-object-instance-from-a-type) – Sriram Sakthivel Oct 03 '13 at 15:01

1 Answers1

5

You can create a non-generic method and use it:

public static T Create<T>() where T : ICreateEmptyInstance, new()
{
    return (T) Create(typeof (T));
}

private static object Create(Type type)
{
    var instance = Activator.CreateInstance(type);

    var properties = type.GetProperties();
    foreach (var property in properties.Where(property => typeof(ICreateEmptyInstance).IsAssignableFrom(property.PropertyType)))
    {
        var propertyInstance = NullObject.Create(property.PropertyType);
        property.SetValue(instance, propertyInstance);
    }

    return instance;
}
CaffGeek
  • 21,856
  • 17
  • 100
  • 184
Vyacheslav Volkov
  • 4,592
  • 1
  • 20
  • 20
  • That looks good, but I got a stack overflow exception! the loop was creating the wrong type I think, now to test this out. – CaffGeek Oct 03 '13 at 15:06
  • what about collections? any thoughts on how to ensure the instance has it's list properties created with empty lists? – CaffGeek Oct 03 '13 at 16:08
  • What exactly do you want, create an empty collection for the type that implements the `ICreateEmptyInstance` interface? – Vyacheslav Volkov Oct 03 '13 at 16:12
  • No, when I'm creating `instance` and setting it's properties that implement `ICreateEmptyInstance` I also want to set any properties that are collections or arrays to contain empty collections. – CaffGeek Oct 03 '13 at 16:59