0

I am trying to define a class where "I" have access to all public methods but when I pass an instance off to a user-supplied function, they can only access a subset of the public methods. Something along these lines:

// usercl.cs
class UserClass {
    public void UserM1();
    public int UserM2(int x);
}

// mastercl.cs
class MasterClass : UserClass {
    public void MasterM3(float y);
    public float MasterM4(int z);
}

// UserCode.cs
...
public void UserFunction(UserClass uc);
...

// Master.cs
MasterClass  mc = new MasterClass();
UserFunction( (UserClass)mc );

But, of course, as implemented above, the user can simply recast it to (MasterClass) and then have access to the Master methods. I tried putting the UserClass in a separate (user) namespace but this ran into a "Cannnot convert type X to Y" compile error in the call to the UserFunction.

I also tried various things with multiple Interface instances (IMaster / IUser), none of which seemed to work, and a couple stabs at using abstract classes (which hurt my head and produced no better results).

What DID seem to work was to define the MasterClass within my code. I could then recast it to "(UserClass)" when calling the UserFunction and the user would not have visibility to the Master methods. However, give that I may need to have a (large?) number of such classes, this is really going to clutter up my primary program/file. I'd be interested in knowing if there is a better/nicer/easier/(?) way to do what I want?

  • See "Explicit Interfaces". Make an Interface Internal. – user2864740 Dec 30 '17 at 23:29
  • 1
    @user2864740: I don't see how that would help. Anything that can cast to the concrete class type will still be able to access everything. – Jon Skeet Dec 30 '17 at 23:30
  • @JohnSkeet Not if implementing the interface explicitly and keeping the internal interface internal. (I assumed that there are split assemblies.. although then might just as well have an `internal` base class member.) – user2864740 Dec 30 '17 at 23:30
  • 1
    Does everything have to be in the same assembly? If UserClass is in a different assembly to MasterClass, and doesn't have a reference to that assembly, they wouldn't be able to cast. – Jon Skeet Dec 30 '17 at 23:31
  • 3
    What is incentive behind this decision? Anyone can still access and call methods via reflection. If you only need access in same assembly you could simply mark method with internal keyword. – CrudaLilium Dec 30 '17 at 23:33
  • @JonSkeet I'm still trying to figure out how to structure this, but the ideal would be to have everything in the same assembly. If this isn't possible, I'd consider separate assemblies, but for a number of reasons (mostly pertinent to this particular project), it's not my preferred solution.. – JudgeRoyBean Jan 12 '18 at 19:39
  • @CrudaLilium As I (just) noted, the goal is to be able to have "everything" in the same assembly, so I don't think "Internal" would solve this. – JudgeRoyBean Jan 12 '18 at 19:43
  • I realize that split assemblies would make it easier to accomplish what I want, but _if_possible_ I'd like to find a solution that doesn't require that. – JudgeRoyBean Jan 12 '18 at 19:46
  • @JudgeRoyBean Well then, your options you have are to either use interface or use adapter pattern, but as I have said before, anyone can use reflection to call your methods regardless of what approach you choose, so if you are trying to achieve some kind of security via your code then you are wasting time. – CrudaLilium Jan 17 '18 at 15:41
  • @CrudaLilium Thank-you (one and all) for your input. It appears I'm over my head here. My current knowledge base is clearly insufficient to accomplish what I'd like to do. Looks like it's either back to school or back to the drawing board. [Sigh. :-) ] – JudgeRoyBean Jan 17 '18 at 21:19

1 Answers1

1

Instead of using inheritance create a wrapper class that implements the "really public" functions. That wrapper simply passes off the parameters to the held instance reference. Because the wrapper doesn't derive from the internal type you don't run into an ability to cast.

SoronelHaetir
  • 14,104
  • 1
  • 12
  • 23
  • I may not fully understand your point, but it seems that while I no longer need to keep the "master" implementation in my primary program file, I will now have an object management issue, since I'll have to deal with separate User/Master objects for each user. While this may solve the code bloating problem, it introduces what feels like a kludge for something I'd like to handle slightly more "elegantly" (if possible). – JudgeRoyBean Jan 12 '18 at 19:34