1

Prior I'd like to appologize for the long title but I didn't figure out a shorter version.

I have an abstract base class that delivers generic methods to access functions in test classes, that derive from my base class.

I have a collection of classes that itself have a reference to those test classes.

The struct is:

// A really simplified example for my manager
Collection<AbstractBaseClass> Manager = new Collection<AbstractBaseClass> 
{
    TestClassA();
    TestClassB();
}

Now I come to the point that I need to kill and recreate the instance in the collection of the testclass without knowledge of which testclass is in this collection.

I try to do sth. like (pseudocode)

Manager[0] = null;
Manager[0] = new (object)Manager[0].GetType();

I already stumbled over Get a new object instance from a Type but this - however - doesn't work because CreateInstance is no member of System.Activator. Also I cannot find the ObjectType class.

Long explaination, short question: How can I create a new instance from a class where I only have an Instance?

Thank you very much, ADP.

Community
  • 1
  • 1
AllDayPiano
  • 414
  • 1
  • 4
  • 20
  • You can't construct an instance of type `T` if it is only known at run-time. – Yuval Itzchakov Feb 22 '16 at 10:47
  • The `Activator` class **has** a method `CreateInstance`. Refer to [MSDN](https://msdn.microsoft.com/en-us/library/wccyzw83(v=vs.110).aspx). Search for typos / missing references in your code. – dymanoid Feb 22 '16 at 10:54
  • You'd need to use an [`Activator.CreateInstance`](http://stackoverflow.com/a/7598427/706456). You should be able to figure out the actual type of the object that you have. But to be honest, it looks like you are over-engineering something and there should be much simpler way of doing things. If you describe what you trying to achieve there might be a much easier solution. – oleksii Feb 22 '16 at 10:54
  • It so weird! I closed the IDE, opened it again and the error is gone. I've tried this 3 times but it didn't change anything.... VS2015 is so full of bugs it's horrible! ... – AllDayPiano Feb 22 '16 at 11:00
  • @oleksii: I suppose you're right. My problem is, that my program was never intended to repeat anything. But my boss came in and said "We got to this repeatable"... – AllDayPiano Feb 22 '16 at 11:03

2 Answers2

1

If you know all your classes have a public parameterless constructor you can do:

manager[i] = (AbstractBaseClass)Activator.CreateInstance(manager[i].GetType());
Lee
  • 142,018
  • 20
  • 234
  • 287
1

While you could use Activator.CreateInstance to create instances from a given type, maybe you can solve this in a more optimal way using generics:

public sealed class TestCollection<T> : ICollection<T>
   where T : AbstractBaseClass, new()
{
    private List<T> Tests { get; } = new List<T>();

    public T this[int index] => Tests[index];

    public void Add(T test) => Tests.Add(test);

    // Rest of ICollection<T> members

    public void NewAt(int testIndex) => Tests[testIndex].Insert(testIndex, new T());
} 

Now you don't need reflection anymore, because T must be a class with a public, paramaterless constructor:

TestCollection<AbstractBaseClass> manager = new TestCollection<AbstractBaseClass>();
manager.Add(new Test());
manager.Add(new Test());
manager.Add(new Test());

manager.NewAt(1);

Now you've already created a new instance of Test without reflection on index 1 and you can still access the new object typed as Test using the TestCollectin<T> indexer: manager[1].

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
  • Hi Matías. This is also a solution that I have already found somewhere. Unfortunately my project has already a huge progress and changing it this way would expense a huge effort. I simplyfied my question. In reality, there is no such collection as postet in my question in this form. The collection is another class that holds some other classes and somewhere out there then is my reference :) – AllDayPiano Feb 22 '16 at 11:17
  • @AllDayPiano Well, then you need to be more specific in your questions... :\ BTW I'll leave this answer for future readers – Matías Fidemraizer Feb 22 '16 at 11:18
  • Hi Matias, I'm sorry if you understood my answer as if I don't need it. Sure, this time probably not but it's in general a pretty nice idea and I'll bookmark it in case I'll need something like this in the future. However I made the experience that it's better to reduce the problem to 3 LOC whilst long explainations will always lead to very long discussions. So I hope you understand me :) – AllDayPiano Feb 22 '16 at 11:30
  • @AllDayPiano No problem!! ;) SO isn't only to answer the OP but to provide quality answer for future visitors. It's ok for me – Matías Fidemraizer Feb 22 '16 at 11:34