Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 向类中的每个方法添加方法调用_C#_Java_Design Patterns - Fatal编程技术网

C# 向类中的每个方法添加方法调用

C# 向类中的每个方法添加方法调用,c#,java,design-patterns,C#,Java,Design Patterns,我的课堂上有很多方法: public class A { public string method1() { return "method1"; } public string method2() { return "method2"; } public string method3() { return "method3"; } . . . public string

我的课堂上有很多方法:

public class A {
    public string method1() {
        return "method1";
    }
    public string method2() {
        return "method2";
    }
    public string method3() {
        return "method3";
    }
    .
    .
    .
    public string methodN() {
        return "methodN";
    }
}
我想在每个方法中添加对doSomething()的调用,例如:

public string methodi() {
    doSomething();
    return "methodi";
}

最好的方法是什么?有合适的设计模式吗?

为什么没有单一功能

public string methodi(int i) {
    doSomething();
    return "method" + i.toString();
}
或者,您可以编写一个接受Func参数的函数,并调用此函数而不是您的函数

    public string Wrapper(Func<string> action)
    {
        doSomething();
        return action();
    }

这是AOP(面向方面编程)的典型用例。您需要为方法调用定义插入点,AOP引擎将正确的代码添加到类文件中。当您希望添加日志语句而不使源文件混乱时,通常使用此选项

对于java,您可以添加库


对于C#和.NET,请查看。看起来是个不错的开始

您可以使用反射

public String callMethod(int i) {
  doSomething();  
  java.lang.reflect.Method method;    
  try {
    method = this.getClass().getMethod("method" + i);
  } catch (NoSuchMethodException e) {
    // ...
  }
  String retVal = null;
  try {
    retVal = method.invoke();
  } catch (IllegalArgumentException e) {
  } catch (IllegalAccessException e) {
  } catch (InvocationTargetException e) { }
  return retVal;
}

使用AOP已经是一个很好的答案,这也是我的第一个想法

我试图找到一种不用AOP的好方法,并提出了这个想法(使用Decorator模式):

然后,您可以装饰A(实现I)的结构:


它基本上不是火箭科学,事实上比你的第一个想法产生了更多的代码,但是你可以注入普通的动作,你可以将额外的动作从类A本身中分离出来。此外,您可以轻松地关闭它,或者仅在测试中使用它。

如果doSomething()是一个横切关注点(如您所建议的日志记录),则只适合使用AOP。如果它与类的核心业务相关,AOP只会混淆问题。@artbristol-同意-我的印象是这个问题是关于交叉关注点的:让所有方法调用
doSomething()
(如
log.info(“刚输入的方法”)
)实际上,我确实认为@Naor需要的是代理模式的典型用法,CGLIB()和Dynamic proxy()将完成这项工作。实际上,Spring框架中的AOP在内部使用了很多。从我的asp.net项目转移到aspectj只是为了节省几行代码有点困难(问题被标记为c和java,你没有告诉我们,你有一个asp.net项目…)关于你的“单一函数”建议-每个方法都做其他事情。这只是一个例子。然后第二部分就是答案。很高兴将公共操作作为参数传递。嗯,想知道是否有人使用java动态代理(C#透明代理)来允许通用包装器类…我想,他想做
this.commonAction().run()在每个方法中,避免重复代码。足够好了!这就是我所追求的。只需使用“我”而不是“私下里的最终A”内容;谢谢
public String callMethod(int i) {
  doSomething();  
  java.lang.reflect.Method method;    
  try {
    method = this.getClass().getMethod("method" + i);
  } catch (NoSuchMethodException e) {
    // ...
  }
  String retVal = null;
  try {
    retVal = method.invoke();
  } catch (IllegalArgumentException e) {
  } catch (IllegalAccessException e) {
  } catch (InvocationTargetException e) { }
  return retVal;
}
interface I {
  String method1();
  String method2();
  ...
  String methodN();
}

class IDoSomethingDecorator implements I {
  private final I contents;
  private final Runnable commonAction;

  IDoSomethingDecorator(I decoratee, Runnable commonAction){
    this.contents = decoratee;
    this.commonAction = commonAction;
  }

  String methodi() {
    this.commonAction().run();
    return contents.methodi();
  }
}
I a = new IDoSomethingDecorator(new A(),doSomething);