我有接口和一些实现此接口的类。 我想监听任何将被实例化的对象,并检查该对象是否实现了我的接口。
我的主要原因是存储对这种对象的所有引用,并简单地调用所有对象的接口方法。
答案 0 :(得分:1)
正如Kyle在评论中所说,抽象类的构造函数将是最佳选择。或者必须用于建造这类物体的工厂。
但是,如果这不是一个选项,则可以采用以下方法。
如果"听众"可以全局访问(例如静态),可以向其中添加Register(IYourInterface obj)
和Unregister(IYourInterface obj)
等方法,并确保实现该接口的每个类都将在构造/解构时调用这些方法。不是最干净的方式,但只要你保持这种行为,它就会起作用。
示例:强>
public static class Listener
{
private static List<IMyInterface> objects = new List<IMyInterface>();
public static void Register(IMyInterface obj)
{
if (!objects.Contains(obj))
objects.Add(obj);
}
public static void Unregister(IMyInterface obj)
{
if (objects.Contains(obj)
objects.Remove(obj);
}
public static void DoSomethingWithObjects()
{
foreach (IMyInterface obj in objects)
// do something ...
}
}
public class SomeTestClass : IMyInterface
{
public SomeTestClass()
{
Listener.Register(this);
}
}
答案 1 :(得分:0)
有几种方法可以解决这个问题。
最简单的解决方案是拥有一个继承自的基类。这种方式违背了界面的目的,但这是您可以添加此类代码进行创建的唯一方法。你可以这样做:
public abstract class AbstractBaseClass
{
public AbstractBaseClass()
{
ObjectRegister.StoreReference(this);
}
public abstract void MethodToCall();
}
public class SubClass : AbstractBaseClass
{
public SubClass() : base() //Don't forget 'base()'!
{
//Your code here
}
public override void MethodToCall()
{
Console.WriteLine("Called in SubClass");
}
}
如果要提供默认操作,抽象MethodToCall也可以是虚拟的,但如果它是抽象的,编译器会抱怨您没有以类似于接口的方式实现它。
有点冗长,但在Unity之类的东西中可以看到。在这种情况下,您没有执行x = new Y()
,而是使用公共静态方法(可能是通用方法),为您创建类,注册它,然后返回该实例。假设您的界面被称为&#39; IRegisterable&#39;,您可能会有以下内容:
public static class ObjectRegister
{
//Note the 'where', which constrains T to be something that
//implements IRegisterable
public static T Instantiate<T>() where T:IRegisterable
{
T obj = new T();
StoreReference(obj);
return obj;
}
private static StoreReference(IRegisterable obj)
{
//Do your storing code here. This doesn't even need to be a method
//if your reference storing stuff only happens on object creation
}
}
//Elsewhere, where class 'Thing' implements IRegisterable
Thing x = ObjectRegister.Instantiate<Thing>();
//x is now registered. No need to do x = new Thing()
string y = ObjectRegister.Instantiate<string>();
//Error: string does not implement IRegisterable
不幸的是,以这种方式提供构造函数参数并不容易。你可以使用一个Init()方法,但它可以作为一种伪造构函数。