Yeah. Talk about confusing titles. So this is the scenario: I've a generic class PromiseListener
which looks like this:
public class PromiseListener<T>
{
public virtual void IsResovled(T value)
{
return;
}
public virtual void IsSpoiled()
{
return;
}
}
This class is supposed to be implemented and its methods overridden. An implementation of this class may look like this:
public class TestPromiseListener : PromiseListener<float>
{
public override void IsResovled(float value)
{
System.Diagnostics.Debug.WriteLine("RMI RETURNED VALUE " + value);
}
}
This TestPromiseListener
is what's implemented by users. What I need to do is store listeners in a dictionary (key is irrelevant for this problem). This is the context of the problem: a promise
is an unresolved return-value of a remote method which may eventually resolve to an actual value. A promise is immediately returned when a remote method invocation is made. So then you can "install" a PromiseListener
whose methods have been implemented by a derived class ( TestPromiseListener
). One of these methods is IsResovled
which takes one argument: the return value of the remote method invocation. This method would be called when the remote method invocation finally returns a value.
I'm having trouble storing the objects in a dictionary. I could store the listeners as object
, but I don't see how I could get a listener from the dictionary without knowing the type first, because I would need to know its original type to cast it to. When fetching the PromiseListener I only know the type of the return value (and all information to fetch the right listener from a dictionary). So what I'm asking is: is there a type-safe way to store these generic objects, fetch them and call their methods?
(Some more detailed info as requested - sorry for the wall of text) Both IsResolved
and IsSpoiled
may be called at different times. A promise can resolve if a return value has been received (calls IsResolved
) or it may be spoiled when no return value could be received (due to a network error, for example) (calls IsSpoiled
). The PromiseListener
a user implements may choose to override any of these methods. So internally I have a method which is called when a return value has been received from the network. In this method I have the identifier for the listener (key in the mentioned dictionary), the actual return value (object) and the AssemblyQualifiedName of the return value (which I can use to convert the return value of type object
to the correct type). I'll then have to find the correct listener - which I can because I have its identifier - but I don't know how to fetch it in a type-save way because I don't know what type the listener is supposed to be.
?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)
...
Is there some reason why you can't use a non -generic base class?
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);
}
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.