views:

144

answers:

4

I have created a class say A which has some functions defined as protected.

Now Class B inherits A and class C inherits B. Class A has private default constructor and protected parameterized constructor.

I want Class B to be able to access all the protected functions defined in Class A but class C can have access on some of the functions only not all the functions and class C is inheriting class B.

How can I restrict access to some of the functions of Class A from Class C ?

EDIT:

namespace Db
{
 public class A
  {
  private A(){}
  protected A(string con){assign this value}

  protected DataTable getTable(){return Table;}
  protected Sqlparameters setParameters(){return parameter;}
  }
}

namespace Data
{
 public class B:A
  {
  protected B():base("constring"){}

  protected DataTable output(){return getTable();}
  protected sqlparameter values(param IDataParameter[] parameter){}
  }
}

namespace Bsns
{
 public class C:B
  {
  protected C():base(){}

  protected DataTable show()
     {return values(setparameter());}

  }
}

EDIT

I think what I am trying to do here is Multiple inheritance.

Please check.

class A
{
//suppose 10 functions are declared 
}

class B:A
{
//5 functions declared which are using A's function in internal body
}


class C:B
{
//using all functions of B but require only 4 functions of A to be accessible by C.
}
+1  A: 

I'd suggest that you rethink your design. Maybe there is a simpler way. What if C uses an instance of B instead of deriving from it (composition) ? That way C can use B's public methods but not get access to the protected ones.

Class A should not care about the level/depth of a descendant. If something is marked protected, it should be protected for both B and C (regardless of the depth of the inheritance chain). B may choose to delimit its descendants by tightening the constraints (but this is rare).

If you can tell me more about your context - the problem you are trying to solve.. I can give you a more detailed/useful answer.

Gishu
@Gishu: I hope above details given now may become useful to understand my problem. I was also thinking the same as you suggested. Making B sealed rahter than inheritable.
Shantanu Gupta
@Gishu: Any suggestions, waiting for answer.
Shantanu Gupta
@Shantanu - I need to know what are the real names/responsibilities of A, B and C. Just knowing the function count and access modifiers doesn't help. You can reuse via inheritance as well as composition/delegation. I tend to resort to inheritance only when I am a 100% sure.
Gishu
@Gishu: Here is my details. A will be a class which will have implementation of Database access like connection object, execute non query. This will be put under same namespace where my other reusable code is present. B is my data access layer where I will be calling these function with the name like GetDataTable or something like that. Class C will be my Business Layer where I will be validating all fields. And pass sqlparameteres to data layer for result generation. I hope to see your help or Ques soon.
Shantanu Gupta
@Shantanu - that doesn't sound like inheritance to me. Composition looks like a better fit. C has a B which has an A. Now B can decide which methods of A it wants to expose to C. i.e. B can access all public methods of A. C can access only selected methods of A indirectly via delegating methods of B.
Gishu
@Gishu: Yes That's what I am looking for, But here the problem is I don't want to write any code on B as it will not be a single file. It will have multiple copies that will be using A's functions to perform different different activities and will be accepting the parameteres of those properties or functions that are defined in A. The only soultion that I feel here is to break my Class A into 2 classes. Or make my Class B as sealed. And using its object I should access.
Shantanu Gupta
@Shantanu - not sure I get what you mean that 'I dont want to write any code on B as it will not be a single file'. If there are multiple B like classes that are going to be using A, you can define multiple types which delegate to a contained A instance.
Gishu
+2  A: 

It looks like you should probably using Composition not Inheritance.

Class A implements calc() and allow().

Class B has a private A but isn't derived from A

Class C derives from B and has no access to the private A object in class B.

Hightechrider
A is being used by B as a base() i.e. inheritance constructor calling.
Shantanu Gupta
+4  A: 

You need to have classes A and B in the same assembly and class C in another assembly. You can mark the member you want to restrict access to by derived classes as protected internal. This makes the member, well, protected and internal. As far as limiting class C's access to the member it will suffice to mark it internal. Since this will make it it public within the first assembly, you might want to add protected to enforce encapsulation.

Turns out marking a member protected internal doesn't make it private to classes outside of the assembly. Seems that for all intents and purposes protected internal is the same as protected. Unfortunately the only way I can see achieving this would be to mark it internal and put up with the member being public to the defining assembly.

Even C# programming guide on MSDN gets it wrong:

By combining the protected and internal keywords, a class member can be marked protected internal — only derived types or types within the same assembly can access that member.

Phil Haack explains:

protected internal means protected OR internal

It’s very clear when you think of the keywords as the union of accessibility rather than the intersection. Thus protected interna means the method is accessible by anything that can access the protected method UNION with anything that can access the internal method.

Here is the updated code:

 class A {
  protected void Test3(){} //available to subclasses of A in any assembly
  protected internal void Test() { } //Same as protected :(
  public void Test2(){}//available to everyone
  internal void Test4(){} //available to any class in A's assembly 
 }

 class B : A {
  void TestA() {
   Test(); //OK
  }
 }
 //Different assembly
 class C : B {
  void TestA() {
   Test4(); //error CS0103: The name 'Test4' does not exist in the current context
  }
 }
Igor Zevaka
@lgor: In this case, how will i be able to use other six functions that were defined in Class A, by making them public ?
Shantanu Gupta
Yep. see code for clarification.
Igor Zevaka
I wish I could upvote this more than once. Great illustration!!
mynameiscoffey
-1 'protected internal' members are visible to any derived type, whether it's in the same assembly or not.
TobiasBohnen
Yep, I just realised that too.
Igor Zevaka
A: 

As others have said, you probably want to use composition instead of inheritance.

class A {
    protected void Foo() { … }
    protected int Bar() { … }
}

class B {
    private A a;

    public B() {
        this.a = new A();
    }

    protected int Bar() {
        return a.Bar();
    }
}

class C : B { … }

Looking at your example, though, I would question whether C should inherit from B, or whether it should really just hold a reference to an object of type B.

Personally, I wouldn't go putting classes in different assemblies just for the purpose of restricting access if the class doesn't otherwise logically belong in a different assembly. There are other ways to handle it.

ICR
Shantanu Gupta