C# 有没有一种方法可以;凌驾;有反射的方法?

C# 有没有一种方法可以;凌驾;有反射的方法?,c#,reflection,.net-reflector,C#,Reflection,.net Reflector,如果没有继承而只有反射,就可以在C#中动态更改方法的代码 比如: nameSpaceA.Foo.method1 = aDelegate; 我无法更改/编辑Foo类。 namespace nameSpaceA { class Foo { private void method1() { // ... some Code } } } 我的最终目标是动态更改以下代码: public static IList<XPat

如果没有继承而只有反射,就可以在C#中动态更改方法的代码

比如:

nameSpaceA.Foo.method1 = aDelegate;
我无法更改/编辑Foo类。

namespace nameSpaceA
{
  class Foo
  {
       private void method1()
       {
           // ... some Code
       }
  }
}
我的最终目标是动态更改以下代码:

public static IList<XPathNavigator> EnsureNodeSet(IList<XPathItem> listItems);
进入:

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

这个答案的第一部分是错误的,我留下它只是为了让评论中的演变有意义。请参阅编辑。

namespace nameSpaceA
{
  class Foo
  {
       private void method1()
       {
           // ... some Code
       }
  }
}
你找的不是反射,而是发射(反过来)

特别是,有一种方法可以满足你的需要,你真幸运

编辑:
写下这个答案,我只记得这也允许你这么做。不过要难多了

Re mix是一个在C#中“模拟”混合的框架。在其基本方面,您可以将其视为与默认实现的接口。如果你更进一步,它会变得比这多得多

编辑2:下面是一个用于重新混合的示例(在不支持INotifyPropertyChanged的类上实现INotifyPropertyChanged,并且不知道混合)

具有完全相同的效果。这是您希望在何处定义特定mixin应用于特定类的问题

示例2:覆盖Equals和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<>))
        {

        }
    }
public class equalablebyvaluesmixin:Mixin,IEquatable其中T:class
{
私有静态只读字段信息[]m_TargetFields=typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
布尔等式等于(T其他)
{
如果(其他==null)
返回false;
if(Target.GetType()!=other.GetType())
返回false;
对于(int i=0;i

这个例子是我用re mix实现的动手实验室。你可以在那里找到更多信息。

不,C#不能被猴子修补,如果这是个问题的话…@MarcGravel。此外,重新混合也可以做到这一点。C#完全可以用猴子修补@Baboon在您的回答中回答:您不能使用DefineMethodOverride更改内部类上的私有非虚拟方法。如果可以的话,我很想看看。同样,您还需要更改构造以创建子类型,这假设您可以控制任何创建
Foo
(不一定是这样)@marcGravel我个人没有尝试过,但我倾向于认为重写私有方法没有意义。然而,考虑到他在编辑后给出的示例场景,在我看来,他似乎可以访问他想要覆盖的方法。所以,这不是私人的。无论哪种方式,重新混合绝对值得一看!“我可以在reflector中看到该方法的功能”和“它是我可以访问的公共虚拟方法”之间存在差异-我真的不认为emit在这方面会有所帮助(我说作为经常使用emit的人)是的,他想要覆盖的方法可能不是虚拟的,或者根本就没有问题。排放不会那么容易起作用。然而,他可以通过反射“读”和发射“写”来重建整个类型。根据类的大小,它可能需要很多工作。在我的情况下,我需要发出一个静态方法,我应该停止工作,尝试使用DefineMethodOverride还是尝试使用re-mix?
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
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<>))
        {

        }
    }