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.

- 23
- 4
-
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 Answers
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.

- 3,651
- 16
- 30
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
{
}

- 15,025
- 28
- 93
- 119
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);
}

- 1
- 1

- 1,563
- 1
- 17
- 24