存储泛型类并在其非泛型派生类中调用重写的方法

本文关键字:调用 重写 方法 派生 泛型 泛型类 存储 | 更新日期: 2023-09-27 17:59:01

>是的。谈论令人困惑的标题。所以这是场景:我有一个泛型类PromiseListener看起来像这样:

public class PromiseListener<T>
{
    public virtual void IsResovled(T value)
    {
        return;
    }
    public virtual void IsSpoiled()
    {
        return;
    }
}

应该实现此类并重写其方法。此类的实现可能如下所示:

public class TestPromiseListener : PromiseListener<float>
{
    public override void IsResovled(float value)
    {
        System.Diagnostics.Debug.WriteLine("RMI RETURNED VALUE " + value);
    }
}

TestPromiseListener是用户实现的内容。我需要做的是将侦听器存储在字典中(键与此问题无关(。这是问题的上下文:promise是远程方法的未解析返回值,最终可能会解析为实际值。进行远程方法调用时,会立即返回承诺。因此,您可以"安装"其方法已由派生类(TestPromiseListener(实现的PromiseListener。其中一个方法是 IsResovled 它接受一个参数:远程方法调用的返回值。当远程方法调用最终返回值时,将调用此方法。

我在字典中存储对象时遇到问题。我可以将侦听器存储为 object ,但我不明白如何在不先知道类型的情况下从字典中获取侦听器,因为我需要知道它的原始类型才能将其转换为。在获取 PromiseListener 时,我只知道返回值的类型(以及从字典中获取正确侦听器的所有信息(。所以我要问的是:有没有一种类型安全的方式来存储这些泛型对象,获取它们并调用它们的方法?

(根据要求提供一些更详细的信息 - 对不起文字墙(IsResolvedIsSpoiled可能会在不同的时间调用。如果已收到返回值(调用 IsResolved(,则承诺可以解析,或者在无法接收返回值时(例如,由于网络错误((调用 IsSpoiled(时可能会被破坏。用户实现PromiseListener可以选择重写这些方法中的任何一个。所以在内部我有一个方法,当从网络收到返回值时调用该方法。在这种方法中,我有侦听器的标识符(上述字典中的键(,实际返回值(对象(和返回值的AssemblyQualifiedName(我可以用来将类型object的返回值转换为正确的类型(。然后,我必须找到正确的侦听器 - 我可以,因为我有它的标识符 - 但我不知道如何以类型保存的方式获取它,因为我不知道侦听器应该是什么类型。

?Type? listener; // Don't know what type the listener is. Could be PromiseListener<string> or PromiseListener<int> - or anything, really
if(promiseManager.TryGetPromiseListener(promise, out listener)
...

存储泛型类并在其非泛型派生类中调用重写的方法

有什么

原因不能使用泛型基类吗?

public abstract class PromiseListenerBase
{
    public abstract Type PromisedType { get; }
    public abstract void HandleResolution(object value);
}
public class PromiseListener<T> : PromiseListenerBase
{
    public override Type PromisedType
    {
        get { return typeof(T); }
    }
    public override void HandleResolution(object value)
    {
        T val = (T)value;
        this.IsResolved(val);
    }
    public virtual void IsResolved(T value) { /* some logic */ }
    public virtual void IsSpoiled() { /* some logic */ }
}
public class FloatListener : PromiseListener<float>
{
    public override void IsResolved(float value)
    {
        Console.Out.WriteLine("FloatListener value {0}", value);
    }
}
public class IntListener : PromiseListener<int>
{
    public override void IsResolved(int value)
    {
        Console.Out.WriteLine("IntListener value {0}", value);
    }
}
public class SomethingUsingPromiseListeners
{
    public void SomeMethod()
    {
        Dictionary<string, PromiseListenerBase> listeners =
            new Dictionary<string, PromiseListenerBase>();
        listeners.Add("float", new FloatListener());
        listeners.Add("int", new IntListener());
        int someValue = 123;
        foreach (PromiseListenerBase listener in listeners.Values)
        {
            if (listener.PromisedType == someValue.GetType())
            {
                listener.HandleResolution(someValue);
            }
        }
    }
}