假设我有一个班级Abc
:
class Abc {
}
我想在外部添加一些方法m()
。我想这可能有可能做到这一点,虽然我不知道如何。假设有可能这样做,那么让我们说从现在开始Abc确实有m()
方法。
现在,想象一下我有其他课程Def
:
class Def {
public void x(Abc abc) {
abc.m();
}
}
此代码是否会与PostSharp一起运行?对于更分散注意力的读者来说,问题在于,在标准的C#类程序中,我们的编译器可能不知道Abc
类具有m()
方法。
我的直觉是,这不适用于PostSharp。我错了吗?
答案 0 :(得分:3)
(如果我的PostSharp解决方案还不够,你可以使用DLR来完成吗?)
是的,你可以。您将在实例作用域方面使用introductionmember属性。最好的办法是使用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&lt;&gt;()函数存在一些问题,它不会进行实际的转换。编译结果如下:
private static void Main(string[] args)
{
Customer c = new Customer();
ISomething cc = c;
cc.SomeMethod();
}
答案 1 :(得分:0)
如果该类位于不同的程序集中,则可以执行此操作。
另一方面,如果类在同一个模块中,那么你是对的,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();
}
}