C# 侦听对象实例化
我有接口和一些实现这个接口的类。 我想要监听任何将被实例化的对象,并检查这个对象是否实现了我的接口C# 侦听对象实例化,c#,.net,object,garbage-collection,C#,.net,Object,Garbage Collection,我有接口和一些实现这个接口的类。 我想要监听任何将被实例化的对象,并检查这个对象是否实现了我的接口 我的主要原因是存储对此类对象的所有引用,并简单地调用所有对象的接口方法 正如凯尔在评论中所说,抽象类的构造函数将是最佳选择。或者是一个必须用来建造这些物品的工厂 但如果这不是一个选项,那么在您的情况下,以下方法可能是可以接受的 如果“侦听器”是全局可访问的(例如,某个静态对象),则可以向其添加方法,如Register(iyointerface obj)和Unregister(iyointerfac
我的主要原因是存储对此类对象的所有引用,并简单地调用所有对象的接口方法 正如凯尔在评论中所说,抽象类的构造函数将是最佳选择。或者是一个必须用来建造这些物品的工厂 但如果这不是一个选项,那么在您的情况下,以下方法可能是可以接受的 如果“侦听器”是全局可访问的(例如,某个静态对象),则可以向其添加方法,如
Register(iyointerface obj)
和Unregister(iyointerface 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);
}
}
公共静态类侦听器
{
私有静态列表对象=新列表();
公共静态无效寄存器(IMyInterface obj)
{
如果(!objects.Contains(obj))
对象。添加(obj);
}
公共静态无效注销(IMyInterface obj)
{
if(objects.Contains(obj)
对象。移除(obj);
}
公共静态void DoSomethingWithObjects()
{
foreach(对象中的IMyInterface对象)
//做点什么。。。
}
}
公共类SomeTestClass:IMyInterface
{
公共SomeTestClass()
{
注册(这个);
}
}
正如凯尔在评论中所说,抽象类的构造函数将是最佳选择。或者,必须使用工厂来构造此类对象
但如果这不是一个选项,那么在您的情况下,以下方法可能是可以接受的
如果“侦听器”是全局可访问的(例如,某个静态对象),则可以添加方法,如Register(iyointerface obj)
和Unregister(iyointerface 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);
}
}
公共静态类侦听器
{
私有静态列表对象=新列表();
公共静态无效寄存器(IMyInterface obj)
{
如果(!objects.Contains(obj))
对象。添加(obj);
}
公共静态无效注销(IMyInterface obj)
{
if(objects.Contains(obj)
对象。移除(obj);
}
公共静态void DoSomethingWithObjects()
{
foreach(对象中的IMyInterface对象)
//做点什么。。。
}
}
公共类SomeTestClass:IMyInterface
{
公共SomeTestClass()
{
注册(这个);
}
}
有几种方法可以做到这一点
使用基抽象类
最简单的解决方案是拥有一个所有内容都从中继承的基类。这种方法有违接口的目的,但这是添加此类代码以进行创建的唯一方法。您可以执行以下操作:
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");
}
}
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
如果您想提供默认操作,抽象MethodToCall也可以是虚拟的,但是如果它是抽象的,编译器会抱怨您没有以与接口类似的方式实现它
使用公共静态实例化方法
更详细一点,但可以在Unity之类的东西中看到。在这种情况下,您没有执行x=new Y()
,而是使用一个公共静态方法,可能是一个泛型方法,它为您创建类,注册它,然后返回该实例。假设您的接口名为“IRegisterable”,您可以使用以下方法:
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");
}
}
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
公共静态类ObjectRegister
{
//注意“where”,它将T约束为
//实现可注册的
公共静态T Instantiate(),其中T:i可注册
{
T obj=新的T();
存储参考(obj);
返回obj;
}
专用静态StoreReference(IRegisterable obj)
{
//在这里存储代码。这甚至不需要是一个方法
//如果引用只在对象创建时存储内容
}
}
//在其他地方,类“Thing”实现了IRegisterable
Thing x=ObjectRegister.Instantiate();
//x现在已注册。无需执行x=新事物()
字符串y=ObjectRegister.Instantiate();
//错误:字符串未实现IRegisterable
不幸的是,以这种方式提供构造函数参数并不容易。您可以只使用一个Init()方法,它充当一种伪构造函数。有几种方法可以做到这一点 使用基抽象类 最简单的解决方案是拥有一个所有内容都从中继承的基类。这种方法有违接口的目的,但这是添加此类代码以进行创建的唯一方法。您可以执行以下操作:
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");
}
}
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
如果您想提供默认操作,抽象MethodToCall也可以是虚拟的,但是如果它是抽象的,编译器会抱怨您没有以与接口类似的方式实现它
使用公共静态实例化方法
更详细一点,但可以在Unity之类的东西中看到。在这种情况下,您没有执行x=new Y()
,而是使用一个公共静态方法,可能是一个泛型方法,它为您创建类,注册它,然后返回该实例。假设您的接口名为“IRegisterable”,您可以使用以下方法:
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");
}
}
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
公共静态类ObjectRegister
{
//注意“where”,它将T约束为
//实现可注册的
公共静态T Instantiate(),其中T:i可注册
{
T obj=新的T();
存储参考(obj);
返回obj;
}
专用静态StoreReference(IRegisterable obj)
{
//在这里存储代码。这甚至不需要