反射を伴う方法を「オーバーライド」する方法はありますか?
-
13-12-2019 - |
質問
継承なしではなく、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);
. 解決
この答えの最初の部分は間違っています、私はそのコメントの進化が理にかなっているようにそれを残すだけです。編集(S)をご覧ください。
あなたは反射を探していませんが、排出量(これは周りの反対側です)。
特に、あなたが望むものだけ、ラッキーなあなたのことをする方法があります!typeBuilder.DefineMethoDoverride
編集:
この答えを書くと、 re-mix を覚えていました。それは難しいです。
再混在は、C#のミックスインシンを「シミュレート」するフレームワークです。その基本的な側面では、デフォルトの実装とインターフェイスと考えることができます。さらに行った場合は、それ以上のものになります。
編集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:等間化等および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<>))
{
}
}
.
その例は、再混合で与えられた実験室の実装です。詳細情報を見つけることができます。
所属していません StackOverflow