おそらくDLRの助けを借りて、リフレクションを使用してコードを発行せずにC#でインターフェースを動的に実装することが可能です。
つまり、次のことができるファクトリを作成します。
IComparable comparable = factory.Create<IComparable>();
ロズリンの方法のいずれか。
おそらくDLRの助けを借りて、リフレクションを使用してコードを発行せずにC#でインターフェースを動的に実装することが可能です。
つまり、次のことができるファクトリを作成します。
IComparable comparable = factory.Create<IComparable>();
ロズリンの方法のいずれか。
私は間違っているかもしれませんが、Mixins を探しているようです。
それらは C# では正式にサポートされていませんが、幸いなことにリミックス プロジェクト(リモーションの一部) があります。
私は過去にそれを使用しましたが、うまく機能します。例を次に示します。
/// <summary>
/// This <see cref="Mixin"/> is used to "automatically" implement <see cref="INotifyPropertyChanged"/> to a target class.
/// <para>It will also override <c>ToString()</c> to show it's possible.</para>
/// </summary>
/// <example>This example adds <see cref="INotifyPropertyChanged"/> to <see cref="INPCTester"/>
/// <code>
/// [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");
/// }
/// }
/// }
/// }
///
/// class Program
/// {
/// static void Main(string[] args)
/// {
/// INPCImplementation();
/// }
///
/// 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!";
/// Console.WriteLine(inpc.ToString());
/// ((INotifyPropertyChanged)inpc).PropertyChanged -= inpc_PropertyChanged;
/// Console.WriteLine();
/// }
/// }
///
/// //Outputs:
/// //
/// //INPC implementation and usage
/// //The resulting object is castable as INPC: True
/// //Hello, world! Property's name: Name
/// //Modified tostring!
/// </code>
/// </example>
/// <remarks>
/// The <see cref="ImplementsINPCAttribute"/> is syntactic sugar for
/// <para> <c>[Uses(typeof(INotifyPropertyChangedMixin))]</c> on top of the target class</para>
/// <para>Which is equivalent to: </para>
/// <para> <c>[assembly: Mix(typeof(INPCTester), typeof(INotifyPropertyChangedMixin))]</c> outside the namespace.</para>
/// <para>or <c>[Extends(typeof(INPCTester))]</c> on top of the mixin class</para>
/// </remarks>
public class INotifyPropertyChangedMixin : Mixin<object>, ICustomINPC
{
public event PropertyChangedEventHandler PropertyChanged;
/// <inheritdoc />
public void RaisePropertyChanged(string prop)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(prop));
}
}
/// <inheritdoc />
[OverrideTarget]
public new string ToString()
{
return "Modified tostring!";
}
}
public class ImplementsINPCAttribute : UsesAttribute
{
public ImplementsINPCAttribute()
: base(typeof(INotifyPropertyChangedMixin))
{
}
}
INPCTester クラスは INotifyPropertyChanged を実装していませんが、それにキャストして実装したかのように扱うことができることに注意してください。
高度な使用法では、アプリケーションの存続期間中に新しく作成されたオブジェクトの型を変更できます。
おそらくDLRの助けを借りて、リフレクションを使用してコードを発行せずにC#でインターフェースを動的に実装することが可能です。
はい、そう思います。Bill Wagner には、 Implementing Dynamic Interfacesという記事があります。IDynamicMetaObjectProvide
インターフェイス、特にDynamicMetaObject
クラスを使用して独自の動的オブジェクトをロールする方法を示します。ただし、これはやや複雑な概念であり、ある時点で、インターフェースのメンバーを対応する DLR 表現に接続するために何らかのリフレクションが必要になります。
ExpandoObject
実装されたインターフェイス (実際には 1 つのインターフェイスのみ) は動的に変更できないため、既存の動的オブジェクトを使用することはできません。