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)
{
//在这里存储代码。这甚至不需要