5

Possible Duplicate:
c# internal abstract class, how to hide usage outside assembly

I have a common assembly/project that has several abstract classes. When I create a new assembly, the developer should derive from MathProblem and MathProblemTemplate<T> classes.

So, I guess the class MathProblemTemplate can be internal, I mean when you plan to set a base class to a concrete class, not show in intellisense the class MathProblemTemplate, but yes for MathProblemTemplate<T>

// Question classes
public abstract class Question
{
    protected QuestionTemplate Template { get; private set; }

    public Question(QuestionTemplate template)
    {
        this.Template = template;
    }
}

public abstract class MathProblem : Question
{
    public MathProblem(MathProblemTemplate template)
        : base(template)
    {
    }
}

// QuestionTemplate classes
public abstract class QuestionTemplate
{
    public QuestionTemplate() { }
}

// This is the class which I'd like to hide
public abstract class MathProblemTemplate : QuestionTemplate
{
}

public abstract class MathProblemTemplate<T> : MathProblemTemplate
{
    protected abstract T Method1();
    protected abstract T Method2(); 
}

Is this possible?

Community
  • 1
  • 1
Darf Zon
  • 6,268
  • 20
  • 90
  • 149
  • Have you read [this relevant question](http://stackoverflow.com/questions/1244953/c-sharp-internal-abstract-class-how-to-hide-usage-outside-assembly) that showed up in the list when you asked your question? – Tamara Wijsman Oct 12 '12 at 22:18
  • Yes, I've read it, but I'm still getting errors like: Inconsistent accessibility: base class 'DevNinja.Core.Models.MathProblemTemplate' is less accessible than class 'DevNinja.Core.Models.MathProblemTemplate' – Darf Zon Oct 12 '12 at 22:22
  • Hmm, yeah, you're using templates which makes it different. – Tamara Wijsman Oct 12 '12 at 22:25
  • Aside from the nasty friends hack, the answer to the question that @TomWijsman referred you to,says you can't do this. If you want to derive from the class in another assembly, it has to be public. – Tony Hopkinson Oct 12 '12 at 22:28
  • Well my intention is just to show the generic class and hide the non generic – Darf Zon Oct 12 '12 at 22:29
  • What is the motivation for having the non generic version? – Kenneth Ito Oct 12 '12 at 22:31
  • Because my MathProblem class needs in its constructor a concrete class for it, as I can't set a generic value, I set a non generic class – Darf Zon Oct 12 '12 at 22:42
  • Hmm, you should be able to use any concrete class that works in the non generic version with the generic version? If I'm missing something please update the question with a bit more detail in the code. – Kenneth Ito Oct 12 '12 at 22:54
  • What do you mean by 'you should be able to use any concrete class that works in the non generic version with the generic version'? – Darf Zon Oct 12 '12 at 23:09

1 Answers1

3

You can't, the reason is that MathProblemTemplate<T> is public, therefore any class it inherits from also needs to be public.

You could just remove MathProblemTemplate and move any code in it into MathProblemTemplate<T>

Trevor Pilley
  • 16,156
  • 5
  • 44
  • 60
  • But I need a reference from it in MathProblem constructor, that's the reason why I really need the generic – Darf Zon Oct 12 '12 at 22:45
  • In that case, you might have to make MathProblem generic and then supply the generic MathProblemTemplate e.g. `public abstract class MathProblem : Question { public MathProblem(MathProblemTemplate template) { } }` – Trevor Pilley Oct 12 '12 at 22:49
  • But would be redundant because this should be a MathProblemTemplate. Don't you think so? – Darf Zon Oct 12 '12 at 23:03
  • What types do you use in the generic version? – Trevor Pilley Oct 13 '12 at 07:43