可以在 C# 中动态实现接口,而无需使用反射发出代码,也许在 DLR 的帮助下。
我的意思是创建一个允许我们执行以下操作的工厂:
IComparable comparable = factory.Create<IComparable>();
无论是罗斯林的方式。
可以在 C# 中动态实现接口,而无需使用反射发出代码,也许在 DLR 的帮助下。
我的意思是创建一个允许我们执行以下操作的工厂:
IComparable comparable = factory.Create<IComparable>();
无论是罗斯林的方式。
我可能错了,但你似乎在寻找 Mixins。
它们在 C# 中不受官方支持,但幸运的是有 re-mix 项目(re-motion 的一部分)
我过去用过它,效果很好,这里有一个例子:
/// <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,但它可以被强制转换为它并被视为已实现。
高级用法允许您在应用程序的生命周期内修改新创建对象的类型。
可以在 C# 中动态实现接口,而无需使用反射发出代码,也许在 DLR 的帮助下。
是的,我会这么认为。Bill Wagner 有一篇名为实现动态接口的文章。它演示了如何使用IDynamicMetaObjectProvide
接口,特别是DynamicMetaObject
类来滚动你自己的动态对象。然而,它是一个有点复杂的概念,在某些时候需要一些反射来将接口的成员连接到相应的 DLR 表示。
您不能使用已经存在的动态对象,ExpandoObject
因为实现的接口(实际上只有一个接口)不能动态更改。