views:

586

answers:

4

I have backed myself into a a bit of a corner. Here is a simplified version of what I have (in C#):

class OuterClass
{
    private class BadClass
    {
        private int Data;

        public BadClass()
        {
            Data = 0;

            ...
        }
    }

    T Build<T>(Object Input)
    {
        T x = new T();
        ...
        return x;
    }

    void SomeMethod()
    {
        BadClass a = Build<BadClass>(anObject);
        ...
    }
    ...
}

The problem I have is that I now must change the initial value of Data depending on the instance of OuterClass that is creating the BadClass instance. Normally I would simply use a BadClass constructor that takes a parameter:

public BadClass(int Data)
{
    this.Data = Data;
    ...
}

But I use BadClass in several generic types so I must have a parameterless BadClass constructor. Too bad I can't do something like this:

Build<BadClass(5)>(anObject);

So, how do I give a constructor run-time information when I can't pass parameters into the constructor?
Is it possible to create a runtime instance of a BadClass type, give it the information it needs, and then use that in my generic types?

EDIT: I used List as an example generic type but that didn't fully express the depth of my dilemma...
I can create a test in Build to call an init function if I am working with a BadClass, but that is very hacky. I am hoping to find a slightly less ugly way to go about it.

+6  A: 

When you create the List<BadClass>, you are not creating any BadClass instances. Go ahead and create a that way, but when you create a BadClass instance to add to it, that's when you call your parameterized constructor:

List<BadClass> a = new List<BadClass>();
a.Add(new BadClass(1));
a.Add(new BadClass(2));

By the way, having the construction of a BadClass instance depend on which OuterClass is creating it is a bit of a code smell. What you you trying to accomplish?

John Saunders
And why would you not be able to have multiple constructors? ;D'But I use BadClass in several generic types so I must have a parameterless BadClass constructor' got me confused.
wtaniguchi
List was a bad example, a generic type can definitely create an instance of BadClass in it's constructor. I could probably work around this way, but I think my code would smell worse if I had a parameter-less constructor that should never be used. Also, when I originally coded BadClass I did not foresee the need to adjust Data, obviously I screwed up
oillio
wtaniguchi - I can have multiple constructors, but using the class in a generic type means I MUST have a constructor with no parameters. I can no longer build a valid parameter-less constructor.
oillio
@oillio: I think you're confused about when an instance of BadClass will be created. There is no operation on the list that will ever create an instance of BadClass. Are you maybe thinking about serialization?
John Saunders
@John - Check out my edit. Does that better detail my issue?
oillio
+1  A: 

Can you give BadClass an initialization method?

private class BadClass
{
    private int Data;

    public BadClass()
    {
        Data = 0;
        ...
    }

    public void Init(int dataValue)
    {
        Data = dataValue;
    }
}

Then when you create one it is:

BadClass myInst = new BadClass(); // void constructor, as you require.
myInst.Init(5);  // Set the value to 5.
abelenky
+1, I like this pattern -- it's called "two-phase construction" in (some of) the literature, BTW.
Alex Martelli
+2  A: 

If you need to have multiple BadClass types that are variations of generics, you can do so by changing your inheritance tree:

class OuterClass {
    private class BadClassBase {
        // whatever BadClass does 
    }
    private class BadClass : BadClassBase {
        public BadClass(T item) {
            ...
        }
    }
}

Not sure if this is what you're going for but you can then create your List<BadClassBase>.

Rob
This is close to what I needed. It works great as long as data has a limited number of valid values. I removed the parameter-less constructor for BadClass and created multiple inherited classes. So I have BadClass1, BadClass2, etc where their base class is BadClass. Theses classes only contain a single constructor that looks like: public BadClass1() : base(1) { }
oillio
+1  A: 

How about doing something like that?

using System.Collections.Generic;

class OuterClass
{
    private class BadClass
    {
        private int _data;

        public BadClass()
        {
            _data = 0;

        }

        public int Data
        {
          get
          {
             return _data;
          }
          set
          {
             _data = value;
          }
        }

    }

    void SomeMethod()
    {
        List<BadClass> a = new List<BadClass>() 
        { 
          new BadClass() { Data = 7 }, 
          new BadClass() { Data = 9 } 
        };
    }
}