是否可以使用 PostSharp 向类添加方法?如果是,是否可以从其他类引用这些方法?

发布于 2024-11-18 05:32:55 字数 471 浏览 2 评论 0原文

假设我有一个类 Abc:

class Abc {
}

并且我想在外部添加一些方法 m() 到它。我想可能可以做到这一点,尽管我不确定如何做。假设可以做到这一点,那么我们假设从现在开始 Abc 确实有一个 m() 方法。

现在,假设我有其他类 Def

class Def {
    public void x(Abc abc) {
        abc.m();
    }
}

此代码可以与 PostSharp 一起运行吗?对于心烦意乱的读者来说,这样做的问题是,在标准 C# 类程序中,我们的编译器可能不知道 Abc 类有一个 m() 方法。

我的直觉是这不适用于 PostSharp。我错了吗?

Let's say I have a class Abc:

class Abc {
}

and that I'd like to externally add some method m() to it. I guess it's probably possible to do this, although I am not sure how. Assuming it is possible to do that, let's then say Abc does have, from now on, a m() method.

Now, imagine I have other class Def:

class Def {
    public void x(Abc abc) {
        abc.m();
    }
}

Would this code run with PostSharp? To the more distracted reader, the problem with this is that in a standard C# class program, our compiler might not know the Abc class has a m() method.

My gut feeling is that this wouldn't work with PostSharp. Am I mistaken?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不疑不惑不回忆 2024-11-25 05:32:55

(如果我的 PostSharp 解决方案不够,也许您可​​以使用 DLR 来完成?)

是的,您可以。您可以在实例范围的方面中使用介绍成员属性。最好的选择是使用 postshsrp 实现一个接口,然后引用您的目标类作为该接口来公开该方法。您还可以使用 Post.Cast<>() 在设计时访问它。

这里有两种方法可以做到这一点。第一个是通过接口,第二个是使用存根。

方法 1 - 接口

public class Program
    {
        static void Main(string[] args)
        {
            Customer c = new Customer();
            var cc = Post.Cast<Customer, ISomething>(c);

            cc.SomeMethod();
        }
    }

    public interface ISomething
    {
        void SomeMethod();
    }

    [AddMethodAspect]
    public class Customer
    {

    }

    [Serializable]
    [IntroduceInterface(typeof(ISomething))]
    public class AddMethodAspect : InstanceLevelAspect, ISomething
    {

        #region ISomething Members

        public void SomeMethod()
        {
            Console.WriteLine("Hello");
        }

        #endregion
    }

方法 2 - 存根

public class Program
    {
        static void Main(string[] args)
        {
            Customer c = new Customer();
            c.SomeMethod();
        }
    }

    [AddMethodAspect]
    public class Customer
    {
        public void SomeMethod() { }

    }

    [Serializable]
    public class AddMethodAspect : InstanceLevelAspect
    {
        [IntroduceMember(OverrideAction = MemberOverrideAction.OverrideOrFail)]
        public void SomeMethod()
        {
            Console.WriteLine("Hello");
        }
    }

更多信息
以防万一使用 Cast<>() 函数时出现一些问题,它不会执行实际的转换。编译结果如下所示:

private static void Main(string[] args)
        {
            Customer c = new Customer();
            ISomething cc = c;
            cc.SomeMethod();
        }

(Maybe you can use the DLR to accomplish if my PostSharp solutions aren't sufficient?)

Yes you can. You would use introducemember attribute in an instance scoped aspect. Your best bet is to implement an interface using postshsrp then reference your target class as that interface to expose the method. You can also use Post.Cast<>() to access it at design time.

Here are two methods to do this. The first is via an interface, the second is using stubs.

Method 1 - Interface

public class Program
    {
        static void Main(string[] args)
        {
            Customer c = new Customer();
            var cc = Post.Cast<Customer, ISomething>(c);

            cc.SomeMethod();
        }
    }

    public interface ISomething
    {
        void SomeMethod();
    }

    [AddMethodAspect]
    public class Customer
    {

    }

    [Serializable]
    [IntroduceInterface(typeof(ISomething))]
    public class AddMethodAspect : InstanceLevelAspect, ISomething
    {

        #region ISomething Members

        public void SomeMethod()
        {
            Console.WriteLine("Hello");
        }

        #endregion
    }

Method 2 - stubs

public class Program
    {
        static void Main(string[] args)
        {
            Customer c = new Customer();
            c.SomeMethod();
        }
    }

    [AddMethodAspect]
    public class Customer
    {
        public void SomeMethod() { }

    }

    [Serializable]
    public class AddMethodAspect : InstanceLevelAspect
    {
        [IntroduceMember(OverrideAction = MemberOverrideAction.OverrideOrFail)]
        public void SomeMethod()
        {
            Console.WriteLine("Hello");
        }
    }

More Info
Just in case there are some issues with using the Cast<>() function, it doesn't do an actual cast. The compiled result looks like:

private static void Main(string[] args)
        {
            Customer c = new Customer();
            ISomething cc = c;
            cc.SomeMethod();
        }
人生百味 2024-11-25 05:32:55

如果类位于不同的程序集中,您可以执行此操作。

另一方面,如果这些类位于同一个模块中,那么你是对的,C# 编译器不会编译它。为什么不在 C# 中实现这样的 m() ,然后用 PostSharp 替换该实现?

class Abc
{
   public void m()
   {
      throw new NotImplementedException ();
   }
}

编辑:

如果将 m() 放入接口中,然后使用 PostSharp 在类上实现该接口会怎么样?然后您可以通过转换到该接口来调用该方法。

interface IM
{
   void m();
}

class Def {
    public void x(Abc abc) {
       if (abc is IM)
        ((IM) abc).m();
    }
}

You can do it if the class is in a different assembly.

On the other hand, if the classes are in the same module, then you are right, the C# compiler won't compile it. Why not implement m() like this in C#, then replace the implementation with PostSharp?

class Abc
{
   public void m()
   {
      throw new NotImplementedException ();
   }
}

Edit:

What if you put m() in an interface, then use PostSharp to implement the interface on your class? Then you can call the method by casting to that interface.

interface IM
{
   void m();
}

class Def {
    public void x(Abc abc) {
       if (abc is IM)
        ((IM) abc).m();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文