1

Hypothetical situation. Say I had a class which contained numerous private fields. I want it to instantiate every field that it can find with the correct type. So far, I have used

public class TestClass
{
    private SomeClass sc;
    private AnotherClass ac;

    public TestClass()
    {
        var type = GetType();
        var fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
            .Select(x => x.Name)
            .ToList();

        foreach (var f in fields)
            type.GetField(f).SetValue(/*instantiate here*/);
    }
}

How would one instantiate it? (this is assuming the new() constructor in each class is parameterless and is not empty)

Kontorted
  • 226
  • 1
  • 13
  • Filter fields on clr type? Then use set value passing the desired object to apply it to – Mardoxx Apr 07 '18 at 14:35
  • https://stackoverflow.com/a/8113612/3515174 may help – Mardoxx Apr 07 '18 at 14:36
  • Instantiate it with what? Are you sure that they all have default `new()` constructors? What happens when they only have parameterized (or no public) constructors? – Ron Beyer Apr 07 '18 at 14:44
  • @RonBeyer I will update my question to be more specific. Assume they all have non-default `new()` constructors which take no arguments. – Kontorted Apr 07 '18 at 14:45
  • [`Activator.CreateInstance(Type)`](https://msdn.microsoft.com/en-us/library/wccyzw83(v=vs.110).aspx) – Ron Beyer Apr 07 '18 at 14:46
  • so, like `var field = type.GetField(f);` `field.SetValue(field, Activator.CreateInstance(field.GetType()));` ? – Kontorted Apr 07 '18 at 14:49
  • 1
    Yes, although the arguments for `SetValue` are `SetValue(object_to_set, value_to_set)`, so it should be `SetValue(this, Activator.CreateInstance(...))` – Ron Beyer Apr 07 '18 at 14:51
  • @RonBeyer Would you like to create an answer post so that I can mark it as accepted? – Kontorted Apr 07 '18 at 14:56

1 Answers1

2

Activator.CreateInstance(Type) can create an instance from the type. This requires a parameter-less constructor (there are overloads for parameters).

To use it, just modify your code a little bit:

public class TestClass
{
    private SomeClass sc;
    private AnotherClass ac;

    public TestClass()
    {
        var type = GetType();

        type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
            .ToList()
            .ForEach(f => {
                f.SetValue(this, Activator.CreateInstance(f.FieldType);
            });
    }
}
Ron Beyer
  • 11,003
  • 1
  • 19
  • 37