문제

상속이 없지만 반사와 함께 C #?

에서 메소드 코드의 코드를 동적으로 변경할 수 있습니다

같은 것 :

nameSpaceA.Foo.method1 = aDelegate;
.

Foo 클래스를 변경 / 편집 할 수 없습니다.

namespace nameSpaceA
{
  class Foo
  {
       private void method1()
       {
           // ... some Code
       }
  }
}
.

내 최종 목표는 다이나믹티 코드를 변경하는 것입니다.

public static IList<XPathNavigator> EnsureNodeSet(IList<XPathItem> listItems);
.

system.xml.xsl.runtime.xslconvert.cs

켜기 :

if (!item.IsNode)
    throw new XslTransformException(Res.XPath_NodeSetExpected, string.Empty); 
.

:

if (!item.IsNode)
    throw new XslTransformException(Res.XPath_NodeSetExpected, item.value); 
.

도움이 되었습니까?

해결책

이 대답의 첫 번째 부분은 틀렸어, 나는 그것이 댓글의 진화가 의미가 있도록 그것을 떠나는 것입니다. 편집 (들)을 참조하십시오.

당신은 반성을 찾고 있지만, 배출 (다른 방향으로는 다른 방식)입니다.

특히, 당신이 원하는 것을하는 방법은 당신이 운이 좋았습니다!

TypeBuilder.DefineMethodoverRide

편집 :
이 답변을 작성하면
Re-mix 도이 작업을 수행 할 수 있습니다. 그것은 더 힘들어 지지만

재 믹스는 C #에서 믹스 인 "을 시뮬레이션"하는 프레임 워크입니다. 기본 측면에서는 기본 구현으로 인터페이스로 생각할 수 있습니다. 더 나아가면 그 이상이됩니다.

편집 2 : 여기에 다시 믹스 (inotifyPropertyChanged를 지원하지 않는 클래스에 inotifyPropertyChanged 구현),

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Remotion.Mixins;
using System.ComponentModel;
using MixinTest;

[assembly: Mix(typeof(INPCTester), typeof(INotifyPropertyChangedMixin))]

namespace MixinTest
{
    //[Remotion.Mixins.CompleteInterface(typeof(INPCTester))]
    public interface ICustomINPC : INotifyPropertyChanged
    {
        void RaisePropertyChanged(string prop);
    }

    //[Extends(typeof(INPCTester))]
    public class INotifyPropertyChangedMixin : Mixin<object>, ICustomINPC
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public void RaisePropertyChanged(string prop)
        {
             PropertyChangedEventHandler handler = this.PropertyChanged;
             if (handler != null)
             {
                 handler(this, new PropertyChangedEventArgs(prop));
             }
        }
    }

    public class ImplementsINPCAttribute : UsesAttribute 
    {
        public ImplementsINPCAttribute()
            : base(typeof(INotifyPropertyChangedMixin))
        {

        }
    }

    //[ImplementsINPC]
    public class INPCTester
    {
        private string m_Name;
        public string Name
        {
            get { return m_Name; }
            set
            {
                if (m_Name != value)
                {
                    m_Name = value;
                    ((ICustomINPC)this).RaisePropertyChanged("Name");
                }
            }
        }
    }

    public class INPCTestWithoutMixin : ICustomINPC
    {
        private string m_Name;
        public string Name
        {
            get { return m_Name; }
            set
            {
                if (m_Name != value)
                {
                    m_Name = value;
                    this.RaisePropertyChanged("Name");
                }
            }
        }

        public void RaisePropertyChanged(string prop)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(prop));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}
.

및 테스트 :

static void INPCImplementation()
        {
            Console.WriteLine("INPC implementation and usage");

            var inpc = ObjectFactory.Create<INPCTester>(ParamList.Empty);

            Console.WriteLine("The resulting object is castable as INPC: " + (inpc is INotifyPropertyChanged));

            ((INotifyPropertyChanged)inpc).PropertyChanged += inpc_PropertyChanged;

            inpc.Name = "New name!";
            ((INotifyPropertyChanged)inpc).PropertyChanged -= inpc_PropertyChanged;
            Console.WriteLine();
        }

static void inpc_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            Console.WriteLine("Hello, world! Property's name: " + e.PropertyName);
        }
//OUTPUT:
//INPC implementation and usage
//The resulting object is castable as INPC: True
//Hello, world! Property's name: Name
.

주의하십시오 :

[assembly: Mix(typeof(INPCTester), typeof(INotifyPropertyChangedMixin))]
.

[Extends(typeof(INPCTester))] //commented out in my example
.

[ImplementsINPC] //commented out in my example
.

똑같은 효과가 있습니다. 특정 믹스가 특정 클래스에 적용되는 것을 정의하고자하는 곳입니다.

예 2 : equals and gethashcode

public class EquatableByValuesMixin<[BindToTargetType]T> : Mixin<T>, IEquatable<T> where T : class
    {
        private static readonly FieldInfo[] m_TargetFields = typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

        bool IEquatable<T>.Equals(T other)
        {
            if (other == null)
                return false;
            if (Target.GetType() != other.GetType())
                return false;
            for (int i = 0; i < m_TargetFields.Length; i++)
            {
                object thisFieldValue = m_TargetFields[i].GetValue(Target);
                object otherFieldValue = m_TargetFields[i].GetValue(other);

                if (!Equals(thisFieldValue, otherFieldValue))
                    return false;
            }
            return true;
        }

        [OverrideTarget]
        public new bool Equals(object other)
        {
            return ((IEquatable<T>)this).Equals(other as T);
        }

        [OverrideTarget]
        public new int GetHashCode()
        {
            int i = 0;
            foreach (FieldInfo f in m_TargetFields)
                i ^= f.GetValue(Target).GetHashCode();
            return i;
        }
    }

    public class EquatableByValuesAttribute : UsesAttribute
    {
        public EquatableByValuesAttribute()
            : base(typeof(EquatableByValuesMixin<>))
        {

        }
    }
.

그 예는 Re-Mix로 주어진 실습 실험실의 구현입니다. 더 많은 정보를 찾을 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top