gpt4 book ai didi

c# - "override"有没有办法用反射的方法?

转载 作者:IT王子 更新时间:2023-10-29 04:39:32 25 4
gpt4 key购买 nike

没有继承,只有反射,是否可以在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也允许您这样做。不过要难得多。

Re-mix 是一个在 C# 中“模拟”mixin 的框架。在其基本方面,您可以将其视为具有默认实现的接口(interface)。如果你走得更远,它会变得更多。

编辑 2:这是一个用于重新混合的示例(在不支持它且不知道混入的类上实现 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 和 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<>))
{

}
}

该示例是我通过重新混音实现的动手实验。您可以在那里找到更多信息。

关于c# - "override"有没有办法用反射的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9684804/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com