在C#中是否可以创建一个只能从另一个函数中调用的函数?
例如,你可以这样做吗?private void a()
{
b();
c();
...do something else
private void b()
{
..do something but can only be called from a()
}
private void c()
{
..do something but can only be called from a()
}
}
我想要这样做的原因是函数b()
和c()
分割了a()
的一些实现细节,它们只是更清晰,更容易在自己的范围内阅读。但是,这些函数对类没用,因为a()
在调用它们之后会进行一些处理。
答案 0 :(得分:10)
可能使用匿名嵌套函数吗?
答案 1 :(得分:9)
我不担心采取明确的步骤来确保b()
和c()
仅由a()
调用。
担心在类上公开的 public 方法是有意义的,因为你提供了一个外部世界的接口,可能是那些无法访问源代码的人您的班级(或者至少不要担心班级的实施细节)。
在你的课程中,你应该随心所欲地拥有你想要的任何私人方法。代码重用是创建新私有方法的一个原因,但是创建多个较小的,一次性使用的方法来分解更大的私有方法也是一个完全有效(和常见)的原因。
除此之外,为您的代码的未来维护者提供一个简单的评论,如:
//this method should only be called by a()
private void b()
{
...
}
比这里提出的大多数其他解决方案更容易理解。
答案 2 :(得分:6)
使用委托你可以:
public voidMyFunction()
{
Func<string> myFunction=(s)=>Console.WriteLine(s);
foreach(string str in myStringList)
{
myFunction(str);
}
}
答案 3 :(得分:2)
简短的回答是否定的;但是,您可以创建一个匿名委托或lambda表达式作为内部b()方法。
答案 4 :(得分:2)
嗯,你可以使用反射,只需获取调用方法名称,如果它不是A,则抛出异常。
http://www.csharp-examples.net/reflection-calling-method-name/
但是如果b和c是私有的,那么它们只能从该类中调用,如果你是唯一一个编写该类的人,那么我就不会看到问题了。所以在我看来它不是编码问题,而是政策问题。
我只是记录方法标题/注释中的意图。
答案 5 :(得分:2)
你可以使用StackFrame类在运行时检查谁是函数的调用者:
public class MyClass
{
public static void A()
{
B();
}
public static void B()
{
var stackTrace = new StackTrace();
if (stackTrace.FrameCount < 1 || stackTrace.GetFrame(1).GetMethod() != typeof(MyClass).GetMethod("A"))
throw new InvalidOperationException("Not called from A()");
}
}
但那是
1)仅在运行时
2)慢
3)一个非常脏的黑客
答案 6 :(得分:0)
不完全是你可以在他们自己的班级中实现这两者。将b()标记为私有。
答案 7 :(得分:0)
要获得只调用()调用b()的效果,要么像安德鲁所说的那样,通过在类中放置a()和b()并适当地标记b()。如果您在一个完全控制的程序集内部工作,那么如果a()和b()将在不同的类中,但在同一个程序集中,则可以使用internal
而不是private
。然后用户代码无法调用它(来自程序集外部,即来自其应用程序),并且您可以通过策略控制程序集的编写。
答案 8 :(得分:0)
您还可以创建以下内容:
internal abstract class SecretFunctionWrapper
{
private void MySecretFunction()
{
...
}
protected void FunctionWhichCalls()
{
...
MySecretFunction();
}
}
public MyRealClass : SecretFunctionWrapper
{
...
}
这仅适用于一个功能。您也可以尝试嵌套的私有类:
public class A
{
private static class Wrapped
{
private static void A()
{
secred code
}
public static void B()
{
A();
}
}
public void UsingA()
{
Wrapped.B();
}
}
答案 9 :(得分:0)
我不知道,但也许Code by Contracts可能有所帮助,但本身不支持
答案 10 :(得分:0)
在这种情况下可能更容易使用#region
答案 11 :(得分:-1)
您可以使用internal
关键字并将这两个函数放在同一个类中,而将其他函数保留在不同的类中:
http://msdn.microsoft.com/en-us/library/7c5ka91b.aspx