是否可以在C#3或4中执行此操作?也许有一些反思?
class Magic
{
[RunBeforeAll]
public void BaseMethod()
{
}
//runs BaseMethod before being executed
public void Method1()
{
}
//runs BaseMethod before being executed
public void Method2()
{
}
}
修改
有一个替代解决方案,使Magic
成为单例,并将您的代码放在静态实例的getter上。这就是我所做的:
public class Magic
{
private static Magic magic = new Magic();
public static Magic Instance
{
get
{
magic.BaseMethod();
return magic;
}
}
public void BaseMethod()
{
}
//runs BaseMethod before being executed
public void Method1()
{
}
//runs BaseMethod before being executed
public void Method2()
{
}
}
答案 0 :(得分:11)
你不能在C#中自动执行此操作 - 你应该看看AOP,例如与PostSharp。
答案 1 :(得分:9)
有一个替代解决方案,让Magic成为单例,并将您的代码放在静态实例的getter上。这就是我所做的。
public class Magic{
private static Magic magic;
public static Magic Instance{
get
{
BaseMethod();
return magic;
}
}
public void BaseMethod(){
}
//runs BaseMethod before being executed
public void Method1(){
}
//runs BaseMethod before being executed
public void Method2(){
}
}
答案 2 :(得分:3)
你想要的是AOP - 一些指向.NET C#AOP框架的链接:
答案 3 :(得分:2)
我知道它不会直接回答这个问题。但是使用装饰器模式来解决这个问题是一种很好的方法,可以使你的实现保持清洁。
创建界面
public static void showPopup(RichPopup pop, boolean visible) {
try {
System.out.println("entered in showPopup code");
FacesContext context = FacesContext.getCurrentInstance();
if (context != null && pop != null) {
//String popupId = pop.getClientId(context);
String popupId = pop.getId();
System.out.println("ClientID of popup="+popupId);
if (popupId != null) {
System.out.println("Client PopupID is not null");
StringBuilder script = new StringBuilder();
script.append("var popup = AdfPage.PAGE.findComponent('").append(popupId).append("'); ");
if (visible) {
script.append("if (!popup.isPopupVisible()) { ").append("popup.show();}");
} else {
script.append("if (popup.isPopupVisible()) { ").append("popup.hide();}");
}
ExtendedRenderKitService erks = Service.getService(context.getRenderKit(), ExtendedRenderKitService.class);
erks.addScript(context, script.toString());
}
}
System.out.println("completion of showPopup code");
}
catch (Exception e) {
System.out.println("exception occured in showPopup code="+e.getMessage());
throw new RuntimeException(e);
}
}
创建实施
public interface IMagic
{
public void Method1()
{
}
public void Method2()
{
}
}
创建装饰器
public class Magic : IMagic
{
public void Method1()
{
}
public void Method2()
{
}
}
<强>用法强>
public class MagicDecorator : IMagic
{
private IMagic _magic;
public MagicDecorator(IMagic magic)
{
_magic = magic;
}
private void BaseMethod()
{
// do something important
}
public void Method1()
{
BaseMethod();
_magic.Method1();
}
public void Method2()
{
BaseMethod();
_magic.Method2();
}
}
答案 4 :(得分:1)
使用https://github.com/Fody/Fody。许可模式基于自愿捐款,这使其成为PostSharp的更好选择,这对我来说有点贵。
[module: Interceptor]
namespace GenericLogging
{
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Assembly | AttributeTargets.Module)]
public class InterceptorAttribute : Attribute, IMethodDecorator
{
// instance, method and args can be captured here and stored in attribute instance fields
// for future usage in OnEntry/OnExit/OnException
public void Init(object instance, MethodBase method, object[] args)
{
Console.WriteLine(string.Format("Init: {0} [{1}]", method.DeclaringType.FullName + "." + method.Name, args.Length));
}
public void OnEntry()
{
Console.WriteLine("OnEntry");
}
public void OnExit()
{
Console.WriteLine("OnExit");
}
public void OnException(Exception exception)
{
Console.WriteLine(string.Format("OnException: {0}: {1}", exception.GetType(), exception.Message));
}
}
public class Sample
{
[Interceptor]
public void Method(int test)
{
Console.WriteLine("Your Code");
}
}
}
[TestMethod]
public void TestMethod2()
{
Sample t = new Sample();
t.Method(1);
}
答案 5 :(得分:0)
只是为了清楚说明为什么以下实施无法工作:
public class Magic{
private static Magic magic = new Magic();
public static Magic Instance{
get
{
magic.BaseMethod();
return magic;
}
}
public void BaseMethod(){
}
//runs BaseMethod before being executed
public void Method1(){
}
//runs BaseMethod before being executed
public void Method2(){
}
}
如果您只想保留Magic
个对象,该方法将被随机调用:
Magic m = Magic.Instance; //this will trigger unwanted call on BaseMethod
如果有人想要调用BaseMethod
,它将被调用两次:
Magic.Instance.BaseMethod(); //two calls of the BaseMethod
当然有一种解决方法,使用get:
返回不需要的对象var unused = Magic.Instance;
总结一下:这在C#中是不可能的(至少现在)。
答案 6 :(得分:0)
我最近有理由这样做。除了要说明我希望方法DoThisFirst在我要调用的特定方法之前运行之外,我将为您保留用例的大概无聊的细节。仍在学习C#,所以可能不是最好的方法...
using System;
namespace ConsoleApp1
{
class Class1
{
public enum MethodToCall
{
Method2,
Method3
}
public delegate void MyDelegate(int number = 0, bool doThis = false, double longitude = 32.11);
public static void DoThisFirst(int number, bool doThis, double longitude)
{
Console.WriteLine("DoThisFirst has been called.");
}
public static void DoSomethingElse(int number, bool doThis, double longitude)
{
Console.WriteLine("DoSomethingElse has been called.");
}
public static void DoAnotherThing(int number, bool doThis, double longitude)
{
Console.WriteLine("DoAnotherThing has been called.");
}
public static void Main()
{
void Action(MethodToCall methodToCall)
{
MyDelegate myDel;
myDel = new MyDelegate(DoThisFirst);
switch (methodToCall)
{
case MethodToCall.Method2:
myDel += DoSomethingElse;
break;
case MethodToCall.Method3:
myDel += DoAnotherThing;
break;
}
myDel.Invoke();
}
Action(MethodToCall.Method3);
Console.ReadKey();
}
}
}
答案 7 :(得分:0)
是的,可以!使用静态构造函数,它将在引用该类之前运行一次,您可以在其中进行所需的操作。
赞:
public class Magic{
static Magic()
{
BaseMethod();
}
public void BaseMethod(){
}
//runs BaseMethod before being executed
public void Method1(){
}
//runs BaseMethod before being executed
public void Method2(){
}
}
这是Microsoft文档:
答案 8 :(得分:0)
如果您使用依赖注入框架来生成实例,那么您可以使用拦截器进行方法调用。
public class CallLogger : IInterceptor
{
TextWriter _output;
public CallLogger(TextWriter output)
{
_output = output;
}
public void Intercept(IInvocation invocation)
{
_output.Write("Calling method {0} with parameters {1}... ",
invocation.Method.Name,
string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray()));
invocation.Proceed();
_output.WriteLine("Done: result was {0}.", invocation.ReturnValue);
}
}
您可以查看 autofac 的文档和示例以获取更多信息。 https://autofaccn.readthedocs.io/en/latest/advanced/interceptors.html