1

How to restrict the access to a member function if the calling class does not implements specific interface in .Net (C#)
For example:
The class which implements IProfessor only can access IStudent.SetGrade method.

  • I have suggested this as idea in visual studio user voice [link](https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/6971117-provide-a-keyword-to-restrict-accessing-a-member) – Saravanakumar Jan 16 '15 at 17:05

3 Answers3

1

One option you could consider, that might actually make sense since presumably an IProfessor can also only set grades for students they teach / in their classes / subjects etc...

IStudent does not HAVE a SetGrade method but a

GetGradeSetterFor(IProfessor professor)

which returns an object that allows the setting of the appropriate grades. ie it is that object that contains the 'business logic' deciding who can set what. And is given access to private methods on the student by (say) passing a delegate or ref to a private field.

realistically you probably want a GetGradeSetterFor(IGrader grader) for when you allow research students etc to Grade which IProfessor could implement.

of course you can always call aStudent.GetGradeSetterFor(null) but it's communicating to the caller in the signature that they might expect issues, which a simple runtime check of the calling type is not.

you could also just have the IProfessor as a param of SetGrade and even a nice extension method in IProfessor so aStudent.SetGrade(aProfessor, args) becomes aProfessor.SetGrade(aStudent, args).

None of these cause compile time issues with passing in null, but you ARE alerting a developer that an IProfessor might be needed in this situation.

tolanj
  • 3,651
  • 16
  • 30
0

You cannot do it compile time, but runtime.

Derive IProfessor from a base type (IPerson), and call SetGrade with an instance of that base type.

public SchoolStudent : IStudent
{
    void SetGrade(IPerson, int grade)
    {
         if (IPerson is IProfessor)
         {
            set grade ...
         }
    }
}

public interface IProfessor : IPerson
{
   ...

}

public interface IPerson
{
}
Michel Keijzers
  • 15,025
  • 28
  • 93
  • 119
0

First of all, this is not good practice for several reasons. See for instance IS there any way to get a reference to the calling object in c#?

Disregarding that I think it would be possible with something like:

void IStudent.SetGrade(int grade)
{
    StackFrame frame = new StackFrame(1);
    var method = frame.GetMethod();
    var matchingInterface = method.DeclaringType.FindInterfaces(MatchType, null).ToList();

    if (matchingInterface.Count > 0)
    {
        //...
    }
}

private bool MatchType(Type m, object filterCriteria)
{
    return m == typeof(IProfessor);
}
Community
  • 1
  • 1
FishySwede
  • 1,563
  • 1
  • 17
  • 24