Можно ли добавить методы в классы с помощью PostSharp?Если да, то можно ли ссылаться на эти методы из других классов? - PullRequest
4 голосов
/ 01 июля 2011

Допустим, у меня есть класс Abc:

class Abc {
}

, и я бы хотел добавить к нему какой-нибудь метод m().Я думаю, что это возможно возможно, хотя я не уверен, как.Предполагая, что это возможно, скажем, у Abc теперь есть метод m().

Теперь представьте, что у меня есть другой класс Def:

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

Будет ли этот код работать с PostSharp?Для более отвлеченного читателя проблема заключается в том, что в стандартной программе класса C # наш компилятор может не знать, что класс Abc имеет метод m().

Мне кажется, что это неработать с PostSharp.Я ошибаюсь?

Ответы [ 2 ]

3 голосов
/ 01 июля 2011

(Может быть, вы можете использовать DLR для достижения цели, если моих решений PostSharp недостаточно?)

Да, вы можете.Вы могли бы использовать атрибут вводит элемент в области видимости экземпляра.Лучше всего реализовать интерфейс с использованием 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();
        }
0 голосов
/ 01 июля 2011

Вы можете сделать это, если класс находится в другой сборке.

С другой стороны, если классы находятся в одном модуле, то вы правы, компилятор C # не скомпилирует его. Почему бы не реализовать m() как это в C #, а затем заменить реализацию на PostSharp?

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

Edit:

Что если вы положите m() в интерфейс, а затем использовать PostSharp для реализации интерфейса в вашем классе? Затем вы можете вызвать метод, приведя к этому интерфейсу.

interface IM
{
   void m();
}

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