我的问题主要是关于C#中的代码安全案例。
以下是代码:
void foo() {
theFirst();
//some code which needs to call theFirst() before executing goes here
definitelyShouldBeCalledAfterTheFirst();
}
现在我想确保在调用函数theFirst()
的每个范围(基本上是任何方法)中,函数definitelyShouldBeCalledAfterTheFirst()
之后在同一范围内调用。在theFirst()
和definitelyShouldBeCalledAfterTheFirst()
来电之间我需要在大多数时间调用其他函数,我无法在definitelyShouldBeCalledAfterTheFirst()
之后或theFirst()
之前调用函数。
答案 0 :(得分:3)
也许这样的代表可以提供帮助:
void ExecuteBetweenFirstAndSecond(Action action)
{
bool success = false;
try
{
First();
success = true;
action?.Invoke();
}
finally
{
//Uncomment if you want to execute Second only if First wast executed successfully
//if (success)
Second();
}
}
答案 1 :(得分:1)
根据具体情况,有多种方法可以实现这一目标。
@SENya给出great option using delegates。
另一种方法是拥有共享基类(尽管此选项仅适用于一小部分方案)。
abstract class MyBaseClass
{
void doFirst() =>
Debug.WriteLine("Done First");
void definitelyShouldBeCalledAfterTheFirst() =>
Debug.WriteLine("Done After First");
protected virtual void doSomething() =>
Debug.WriteLine("between first and after first");
public void DoStuff()
{
doFirst();
doSomething();
definitelyShouldBeCalledAfterTheFirst();
}
}
class MyClass: MyBaseClass {}
class MyOtherClass: MyBaseClass
{
protected override void doSomething() =>
Debug.WriteLine("something else happens now");
}
void Main()
{
var a = new MyClass();
a.DoStuff();
/* outputs:
Done First
between first and after first
Done After First
*/
var b = new MyOtherClass();
b.DoStuff();
/* outputs:
Done First
something else happens now
Done After First
*/
}
答案 2 :(得分:1)
如果我理解你的问题你有以下要求:
什么功能总是执行并执行第一个?构造函数......
因此,如果您创建一个类并在构造函数中调用First()
函数,则满足要求#1。
确保执行顺序符合要求#3很容易。在构造函数之前不会执行任何代码。如果你设置了一个已经执行了Last()
函数的标志,你可以在每个函数的开头检查该标志,如果已经设置则抛出/返回。
最难的部分是确保执行Last()
功能。最接近的保证是实施IDisposable,但您无法保证在using
内调用您的课程。
所以我们最终得到的结论是:
public sealed class Foo: IDisposable
{
private bool isLastCalled = false;
public Foo()
{
First();
}
public void First()
{
if (isLastCalled) return;
// do something...
}
public void Other()
{
if (isLastCalled) return;
// do something...
}
public void Last()
{
if (isLastCalled) return;
isLastCalled = true;
}
public void Dispose()
{
Last();
}
~Foo()
{
Last();
}
}
附加说明:
First()
将从构造函数自动调用,但您可以在调用Last()
之前再次调用它。如果这不是你的意图 - 制作函数private
并删除检查标志
您可以显式调用Last()
,也可以在实例超出范围时自动调用它。如果您不需要明确调用它,请将其private
答案 3 :(得分:0)
这就是try-finally的用途。非常简单。如果对theFirst的调用成功,那么即使“某些代码”失败,也可以保证对sureShouldBeCalledAfterTheFirst的调用。
void foo()
{
theFirst();
try
{
// some code
}
finally
{
definitelyShouldBeCalledAfterTheFirst();
}
}