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

时间:2014-04-20 12:19:23

标签: c# .net windows-phone-8

呀。谈论令人困惑的头衔。所以这就是场景:我是一个通用类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是远程方法的未解析返回值,最终可能会解析为实际值。在进行远程方法调用时,会立即返回promise。那么你就可以安装&#34;一个PromiseListener,其方法已由派生类(TestPromiseListener)实现。其中一个方法是IsResovled,它接受​​一个参数:远程方法调用的返回值。当远程方法调用最终返回值时,将调用此方法。

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

(根据要求提供更详细的信息 - 抱歉文字墙) 可以在不同时间调用IsResolvedIsSpoiled。如果收到返回值(调用IsResolved),则可以解析promise;如果没有收到返回值,则可能会损坏(例如,由于网络错误)(调用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)
...

1 个答案:

答案 0 :(得分:1)

为什么你不能使用 - 通用基类?

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);
            }
        }
    }
}