我目前的项目中有一个特例。
我有:
public class A
{
// etc.
}
public class B
{
// etc.
private void HandleSomeEvent(object parameter)
{
// Etc.
}
protected void HandleSomeOtherEvent(object parameter)
{
// Etc.
}
}
我想:
A
能够调用私有方法B.HandleSomeEvent
,但没有其他类(但B
)能够执行此操作A
能够调用受保护的方法B.HandleSomeOtherEvent
,但没有其他类(但B
和B
的派生类)能够执行此操作这可能在C#中吗?
B
免于篡改同一个程序集中的类C
?答案 0 :(得分:1)
这可能在C#中吗?
不,除非您使用反射:私人和受保护的成员无法从其他类访问。
如果不可能的话,有哪些替代方案可以尽可能地保护B免受同一组件中C级的篡改?
你可以在B中使B成为嵌套类并使其成为私有。然后你可以安全地增加B的两种方法的可见性,因为只有A才能调用它们(除非使用反射)。
答案 1 :(得分:1)
这是可能的,但我通常会选择internal
并假设程序集中的其他类表现良好。
例如,您可以将这些方法的委托传递给A类,该类将它们存储在protected static
字段/属性中。
答案 2 :(得分:1)
“2。如果不可能的话,有哪些替代方案能够尽可能地保护B免受同一装配中的C级篡改?”
检查调用者的类型信息并抛出异常会有效吗?
[MethodImpl(MethodImplOptions.NoInlining)]
private void HandleSomeEvent(object parameter)
{
StackTrace stackTrace = new StackTrace();
StackFrame stackFrame = stackTrace.GetFrame(1);
MethodBase methodBase = stackFrame.GetMethod();
if(methodBase.DeclaringType == typeof(ClassA)) // Okay.
else if (methodBase.DeclaringType == typeof(ClassB)) // Okay.
else throw new ApplicationException("Not Okay");
}
答案 3 :(得分:1)
可以通过发出A的接口然后将其与具体实现分开。一旦你这样做,你可以写这样的东西
interface IA { }
class A : IA
{
public static IA New() { return new A(); }
private A() { }
private void UseB()
{
var b = new B();
b.HandleSomeEvent(this, null);
}
}
class B
{
public void HandleSomeEvent(A onlyAccess, object parameter) { }
}
尽管HandleSomeEvent()
只是公共的,但是A可以访问它,因为没有其他人可以获得A类的具体实例。它有一个私有构造函数,而工厂New()
方法返回一个接口。
有关详细信息,请参阅我的文章Friends and internal interface members at no cost with coding to interfaces。
答案 4 :(得分:0)
由于您的班级A
应该能够在protected
上调用B
方法,我认为它与它有某种关系。问问自己是否存在“是-a”关系,如“A是B”。在这种情况下,您可以A
继承B
:
public class A : B
{
}
现在,您可以在B
上调用受保护的方法。但是,请不要只是继承,总是问自己遗传是否有意义。
答案 5 :(得分:0)
您可以将这两种方法标记为internal
:
internal void HandleSomeEvent(object parameter)
{
// Etc.
}
protected internal void HandleSomeOtherEvent(object parameter)
{
// Etc.
}
这使得两个方法对同一个程序集中的所有类都可见(以及对B
派生的所有类都可见的第二个方法)。
无法使方法对特定的其他类可见。毕竟,你是那个控制你的程序集中所有类的人,所以你需要确保除了A
之外没有其他类调用这些方法。
如果您确实需要使用此工具的帮助,您可以编写FxCop规则或创建某种后构建操作,以检查来自A
以外的其他类的方法调用。