有没有一种优雅的方法可以让类中的每个方法都从C#中的某个代码块开始

本文关键字:方法 开始 代码 一种 有没有 | 更新日期: 2023-09-27 18:00:45

我有一个类,其中每个方法都以相同的方式启动:

internal class Foo {
  public void Bar() {
    if (!FooIsEnabled) return;
    //...
  }
  public void Baz() {
    if (!FooIsEnabled) return;
    //...
  }
  public void Bat() {
    if (!FooIsEnabled) return;
    //...
  }
}

有没有一种很好的方法可以要求(希望不是每次都写)类中每个公共方法的FooIsEnabled部分?

我检查有没有一种优雅的方法可以让类中的每个方法都从某个代码块开始?,但这个问题是针对Java的,它的答案是使用Java库。

有没有一种优雅的方法可以让类中的每个方法都从C#中的某个代码块开始

您正在寻找的主体是来自面向方面编程或AOP领域的Interception。

虽然C#并不直接支持它,但有一些可靠的选择:

  1. Postsharp
  2. Unity拦截
  3. Spring.NET
  4. 城堡拦截机

如果我明天有时间,我会给你做一个例子。。。

我不认为你可以轻易地消除Bar、Baz、Bat方法中多余的混乱,但你可以通过创建一个方法来执行你传递的操作,使其更易于管理。

internal class Foo
{
    private bool FooIsEnabled;
    public void Bar()
    {
        Execute(() => Debug.WriteLine("Bar"));
    }
    public void Baz()
    {
        Execute(() => Debug.WriteLine("Baz"));
    }
    public void Bat()
    {
        Execute(() => Debug.WriteLine("Bat"));
    }
    public void Execute(Action operation)
    {
        if (operation == null)
            throw new ArgumentNullException("operation");
        if (!FooIsEnabled)
            return;
        operation.Invoke();
    }
}

确定:

internal interface IFoo {
    void Bar();
    void Baz();
    void Bat();
}
internal class Foo {
    private IFoo FooImplementation = new DisabledFoo() // or new EnabledFoor()
    public bool FooIsEnabled
    {
        get
        {
            return FooImplementation is EnabledFoo;
        }
        set
        {
            FooImplementation = value ? new EnabledFoo() : new DisabledFoo()
        }
    }
    public void Bar() {
        FooImplementation.Bar();
    }
    public void Baz() {
        FooImplementation.Baz();
    }
    public void Bat() {
        FooImplementation.Bat();        
    }
}
internal class EnabledFoo : IFoo {
    public void Bar() {
        //...
    }
    public void Baz() {
        //...
    }
    public void Bat() {
        //...
    }
}
internal class DisabledFoo : IFoo {
    public void Bar() {}
    public void Baz() {}
    public void Bat() {}
}

如果您的意图是模拟单元测试的foo实现,只需删除FooIsEnabled属性并将FooImplementation公开即可。在这种情况下,您还应该去掉DisabledFoo,并使用以下实例进行测试:

var fooImplementationMock = new Mock<IFoo>();
var foo = new Foo { FooImplementation = fooImplementationMock.Object };
foo.Bar();
fooImplementationMock.Verify(f => f.Bar());

假设您使用的是moq