可能在C#中動態實現接口,而無需使用反射發射代碼,也許藉助於DLR。動態實現C#接口是否可行
我的意思是創建一個工廠,使我們能夠做到以下幾點:
IComparable comparable = factory.Create<IComparable>();
無論哪種方式羅絲琳。
可能在C#中動態實現接口,而無需使用反射發射代碼,也許藉助於DLR。動態實現C#接口是否可行
我的意思是創建一個工廠,使我們能夠做到以下幾點:
IComparable comparable = factory.Create<IComparable>();
無論哪種方式羅絲琳。
可能在C#中動態實現一個接口,而無需使用反射發射代碼,也許藉助於DLR。
是的,我會這麼認爲。比爾瓦格納有一篇名爲Implementing Dynamic Interfaces的文章。它演示瞭如何使用IDynamicMetaObjectProvide
接口,尤其是DynamicMetaObject
類來爲您推出非常自己的動態對象。然而,這是一個相當複雜的概念,並且在某些時候需要一些反思來將接口的成員連接到相應的DLR表示。
您不能使用已有的動態對象,如ExpandoObject
,因爲實現的接口(實際上只有一個接口)不能動態更改。
我可能是錯的,但它似乎是在尋找Mixins。
他們沒有正式在C#的支持,幸好有the re-mix project
我已經在過去使用它(重新運動的一部分)和它的作品很好,這裏有一個例子:
/// <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,但它可以被轉換爲它,並被視爲它。
高級用法允許您在應用程序的生命週期中修改新創建的對象的類型。
好的,謝謝,但是在某些地方你已經創建了一個對象INotifyPropertyChangedMixin,唯一動態的方法是通過反射發射代碼,然後注入代碼。 –
這聽起來有點舔什麼嘲笑框架對我做... –
它應該怎麼做?這些方法應該什麼都不做?他們是否應該讓代表們瞭解這些方法的作用?他們是否應該有一個擁有方法但沒有實現接口的類?它是否應該找到一些能夠實現接口的隨機類? – Servy
你的意思是說,沒有具體實現'IComparable'註冊或鏈接的方式? – Jodrell