I have a class which works with a hardware device. This device supports a number of commands, and I want to implement a common SendCommand function. Commands might or might not have input parameters and/or output result.
What I can do is to write an abstract command type class, and a number of derived command type classes. Those derived classes would actually be different with those input/output specifics of commands.
Now I want SendCommand to return a Task<SpecificCommandType>, that is, task of derived class, but with current design I can only return Task<BaseCommandType>.
I will explain with simple skeleton code:
Classes:
public abstract class BaseCommandType { ... }
public class CommandType1 : BaseCommandType {
TaskCompletionSource<CommandType1> Tcs;
}
public class CommandType2 : BaseCommandType {
TaskCompletionSource<CommandType2> Tcs;
}
My function:
public Task<T> SendCommand<T>(BaseCommandType type) where T : BaseCommandType {
...
// if I implement TaskCompletionSource<BaseCommandType> Tcs
// in abstract class, then I can return type.Tcs.Task, and remove
// generics.
// But how can I return Task<T>?
}
I was planned to use this func like this:
CommandTypeX cmd = new CommandTypeX(...);
SendCommand<CommandTypeX>(cmd).ContinueWith(t => {
// access some specifics of t.Result as CommandTypeX
});
How should I design my classes to be able to return Task<CommandTypeX>?
Or is there a better way to do something I need (without downcast)?
Update1:
To be more precise, I can do it like this with downcast (can do I, isn't it?):
public abstract class BaseCommandType {
public TaskCompletionSource<BaseCommandType> Tcs;
}
public class CommandTypeX : BaseCommandType { }
public Task<BaseCommandType> SendCommand(BaseCommandType type) {
...
return type.Tcs.Task;
}
// when task finishes:
type.Tcs.SetResult(type); // where type is actually of CommandTypeX
// usage:
CommandTypeX cmd = new CommandTypeX(...);
SendCommand(cmd).ContinueWith(t => {
CommandTypeX command = t.Result as CommandTypeX;
if (command != null) ...
});
But that's exactly what I want to avoid in first place.
Update2:
I think I found another way of going, but still looks not well for me.
public abstract class BaseCommandType {
internal abstract void SetTcs<T>(TaskCompletionSource<T> tcs);
internal abstract void HandleData(byte[] data);
}
public class CommandType1 : BaseCommandType {
private TaskCompletionSource<CommandType1> _tcs1 = new TaskCompletionSource<CommandType1>();
public string Data1;
internal override void SetTcs<T>(TaskCompletionSource<T> tcs)
{
_tcs1 = tcs as TaskCompletionSource<CommandType1>;
}
internal override void HandleData(byte[] data)
{
// Data1 = someFuncOn(data)
_tcs1.TrySetResult(this);
}
}
public class CommandType2 : BaseCommandType {
private TaskCompletionSource<CommandType2> _tcs2 = new TaskCompletionSource<CommandType2>();
public int[] Data2;
internal override void SetTcs<T>(TaskCompletionSource<T> tcs)
{
_tcs2 = tcs as TaskCompletionSource<CommandType2>;
}
internal override void HandleData(byte[] data)
{
// Data2 = someFuncOn(data)
_tcs2.TrySetResult(this);
}
}
public class Device {
private List<BaseCommandType> _commandList = new List<BaseCommandType>();
public Task<T> SendCommand<T>(T t) where T : BaseCommandType
{
TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
t.SetTcs<T>(tcs);
_commandList.Add(t);
// later in other thread then device answers
// locate command in list
// BaseCommandType c = _commandList[some index];
// _commandList.RemoveAt(some index);
// c.HandleData(null);
return tcs.Task;
}
}
// usage like this:
CommandType2 command = new CommandType2();
device.SendCommand<CommandType2>(command).ContinueWith(t =>
{
CommandType2 command2 = t.Result;
// use command2.Data2 here;
});
Is this way better than in update1? At least I can hide the casting logic inside the library so externally everything would be type safe and robust.
Or how can I further improve on this?
I'm not sure whether I understood it right, but...
public abstract class BaseCommandType<T>
{
public abstract TaskCompletionSource<T> Tcs { get; }
}
public class CommandType1 : BaseCommandType<CommandType1>
{
}
public class CommandType2 : BaseCommandType<CommandType2>
{
}
public Task<T> SendCommand<T>(T type) where T : BaseCommandType<T>
{
return type.Tcs.Task;
}
EDIT:
If you cannot have generic input parameter, than instead of downcasting define abstract beahvior on BaseCommandType, which you would call in ContinueWith method, and override it in your commands. If you don't know the input type you cannot make it generic.
Things I don't understand about your question:
Why the restriction on the parameter type for SendCommand<T>(BaseCommandType)? What wouldn't work if you make that method SendCommand<T>(T) instead?
Why are you using ContinueWith()? await would be easier and more expressive.
Ignoring those for a moment, I would expect you should be able to do something like this:
public async Task<T> SendCommand<T>(BaseCommandType type) where T : BaseCommandType
{
return await type.Tcs.Task as T;
}
Personally, I would go all-generic. But you say you can't for whatever reason, so you're going to have to cast at some point. Avoiding casting simply isn't possible with that constraint. The above seems like the easiest, most usable approach to do that.
If the above does not address your need, please improve the question by including a good Minimal, Complete, and Verifiable code example that shows clearly all the design restrictions and requirements, what you've tried, and explain why what you've tried does not meet your goal.
Related
Ok! This is already stressing me for few hours.
I'm using a provided assembly that has an interface I need to implement
public interface ICustomInterface
{
CustomType DoSomething(string name);
}
in my code I do like this:
public class MyClass: ICustomInterface
{
public MyClass()
{
}
// now I should implement the interface like this
public CustomType DoSomething(string name)
{
CustomType nType = new CustomType();
// do some work
return nType;
}
}
So far so good but in my implementation of the interface in the MyClass I need to make use of async await therefore the implementation should be like this:
public class MyClass: ICustomInterface
{
public MyClass()
{
}
// now I should implement the interface like this
public async Task<CustomType> DoSomething(string name)
{
CustomType nType = new CustomType();
await CallSomeMethodAsync();
// do some extra work
return nType;
}
}
And of course this doesn't work because it complains the Interface ICustomerInterface.DoSomething.... is not implemented.
Is there a way to override the interface implementation that accepts async await?
I cannot modify the provided assembly.
That's impossible. If the interface requires the operation to be computed synchronously, then the operation needs to be performed synchronously.
I'm currently have an implementation of Chain of Responsibility which return objects that implement IResponse.
public interface IRequest
{
}
public interface IResponse
{
}
public interface IFactory
{
bool CanHandle(IRequest request);
IResponse HandleRequest(IRequest request);
}
public class Foo : IResponse
{
public void SpecificMethod()
{
Console.WriteLine("SpecificMethod() only belongs to Foo");
}
}
public class FooRequest : IRequest
{
}
public class FooFactory : IFactory
{
public bool CanHandle(IRequest request)
{
return request is FooRequest;
}
public IResponse HandleRequest(IRequest request)
{
return new Foo();
}
}
public class FactoryManager
{
private readonly List<IFactory> _factoryImplementations = new List<IFactory>();
public void Register(IFactory factory)
{
_factoryImplementations.Add(factory);
}
public IResponse HandleRequest(IRequest request)
{
foreach (var factory in _factoryImplementations)
{
if (factory.CanHandle(request))
{
return factory.HandleRequest(request);
}
}
return null;
}
}
class Program
{
static void Main()
{
var manager = new FactoryManager();
manager.Register(new FooFactory());
var foo = (Foo) manager.HandleRequest(new FooRequest()); // How can I remove this cast?
foo.SpecificMethod();
Console.ReadLine();
}
}
The purpose of this implementation is to make it easy to replace implementations whenever I need. The problem is that I have to explicitly cast the type which I made the request for if I want to do anything specific with the object, like accessing foo.SpecificMethod().
Is there any way to have this (Foo) cast gone?
Edit: It's possible to solve this issue with a dynamic variable, but a statically typed way of solving it would be preferrable.
If you want to be able to call a unique function that isn't on the main interface, you will have to cast it (or request a more specific interface with that method on it).
Using an interface means "This method will have these available public methods". You can inherit from multiple interfaces (public interface IMoreSpeific : IGeneric) but you can't make calls to specific class implementations that have other methods without casting it.
You can make something generic like a DoWork() method on your interface, but the purpose of the interface is to have something reusable and generic.
[MAJOR EDITS, my first post was somewhat misleading. My appologies]
Given a class such as:
public class DatabaseResult{
public bool Successful;
public string ErrorMessage;
//Database operation failed
public static DatabaseResult Failed(string message) {
return new DatabaseResult{
Successful = true,
ErrorMessage = message
};
}
}
How can I implement subclasses such that I can add additional properties to represent data relevant to the particular operation (such as MatchedResult in the case of a SELECT type query) without the need to implement that static failure function? If I try to use plain inheritance, the return type will be of the parent class. Eg:
DoThingDatabaseResult : DatabaseResult {
public IEnumerable<object> SomeResultSet;
public static Successful(IEnumerable<object> theResults){
return new DoThingDatabaseResult {
Successful = true,
ErrorMessage = "",
SomeResultSet = theResults
};
}
//public static DatabaseResult Failed exists, but it's the parent type!
}
The goal is to avoid needing to copy the Failed static function for every subclass implementation.
Make it recursively generic:
public class BankAccount<T> where T : BankAccount<T>, new()
{
public T SomeFactoryMethod() { return new T(); }
}
public class SavingsAccount: BankAccount<SavingsAccount>{}
You'll note that I made the factory method non-static, because static methods aren't inherited.
You can't do this exactly as you have defined the question. The best way to tackle this is really to pull your factory out of the class completely:
public class BankAccount
{
}
public class SavingsAccount : BankAccount
{
}
public static class BankAccountFactory
{
public static T Create<T>() where T : BankAccount, new()
{
return new T();
}
}
Now the Factory has no dependency on the actual type. You can pass any derived class of BankAccount and get it back without doing any extra work or worrying about inheriting your factory method.
If I may, I'd like to expand upon StriplingWarrior. In fact, you can use static for the factory. This following code shows that a and c are the expected object types. The limit is you cannot use the factory on the base class itself.
private void Testit()
{
var a = SavingsAccount.Factory();
var c = CheckingAccount.Factory();
//var b = BankAccount.Factory(); //can't do this
}
public class BankAccount<T> where T : BankAccount<T>, new()
{
public static T Factory()
{
return new T();
}
}
public class SavingsAccount : BankAccount<SavingsAccount>
{
}
public class CheckingAccount : BankAccount<CheckingAccount>
{
}
In order to use inheritance, you need an instance of an object and a member of that object. In this case, for the object we can't use BankAccount/SavingsAccount because then we would already have what we're trying to get. This means we need an actual factory object, which is what most people are talking about when they talk about a factory. So if we pull that out into a Factory and use inheritance...
public class BankAccountFactory { public virtual GetAccount() { return new BankAccount(); } }
public class SavingsAccountFactory : BankAccountFactory { public override GetAccount() { return new SavingsAccount(); } }
But now how do we get an instance of the proper type? We've just pushed our problem one layer deeper.
Instead, what you probably want to do, is use some sort of configuration to determine the type, or pass the type you want into a method.
public BankAccount GetAccount(AccountType type) { /* */ }
or
public BankAccount GetAccount() { /* Access config */ }
For a simple answer to your question: You don't need to use generics or anything like that, you just need your method to not be static...
In my app, I have deal with several different "parameters", which derive from IParameter interface, and also ParamBase abstract base class. I currently have two different parameter types, call them FooParameter and BarParameter, which both derive from ParamBase. Obviously, I can treat them both as IParameters when I need to deal with them generically, or detect their specific type when I need to handle their specific functionality.
My question lies in specific FooParameters. I currently have a few specific ones with their own classes which derive from FooParameter, we'll call them FP12, FP13, FP14, etc. These all have certain characteristics, which make me treat them differently in the UI. (Most have names associated with the individual bits, or ranges of bits). Note that these specific, derived FP's have no additional data associated with them, only properties (which refer to the same data in different ways) or methods.
Now, I'd like to keep all of these parameters in a Dictionary<String, IParameter> for easy generic access. The problem is, if I want to refer to a specific one with the special GUI functions, I can't write:
FP12 fp12 = (FP12)paramList["FP12"] because you can't downcast to a derived type (rightfully so). But in my case, I didn't add any data, so the cast would theoretically work.
What type of programming model should I be using instead? Thanks!
There's nothing really wrong with this approach, except for maybe storing the parameters in a dictionary. What is the purpose of doing that? Especially if you key them on their class name.
I would just use a List<IParameter> and have a control go through the collection and pick the right subclass out of there.
m_Parameters = new List<IParameter>();
//This control needs FP12
foreach(var param in Parameters) {
var fp12 = param as FP12;
if (fp12 != null) {
//do something with the param.
break;
}
}
After writing the above I think I finally understand what you are trying to do. If you want to perform an operation that is available on FP12 on any subclass of FooParameter then you need to take that operation out of FooParameter altogether. Since your parameter is data and that data is the same across different subclasses of FooParameter, it makes sense to only have one implementation of FooParameter ("data" class) and multiple "operation" classes.
//The one implementation of IParameter for all FooParameters
public class FooParameter : IParameter {
string Data1 {get;set;}
}
//base class for Foo Operation, only stores FooParameter
public class FooOperationBase {
protected readonly FooParameter m_Param;
public FooOperationBase (FooParameter param) {
m_Param = param;
}
}
//specific operations on FooParameter go in this class
public class FooOperation12 : FooOperationBase {
public FooOperation12(FooParameter param) : base(param) {}
public void DoSomeOperation() {
return m_Param.Data1 + " transformed";
}
}
If paramList["FP12"] is a FP12, that cast will work. Of course, if it's not it will throw a InvalidCastException. You could also use as, if you're not sure what type the object will be.
Whether this is an ideal design is a separate issue. Ideally, you want to prefer polymorphism, meaning the subclass of FooParameter knows to use its new special functions internally, and the outside code doesn't have to cast, or use as or is.
I'm not 100% sure where you're coming from with this question, but you could do something like this:
class Program
{
static void Main(string[] args)
{
var paramList = new List<IParameter>();
paramList.Add(new FooParameter());
paramList.Add(new BarParameter());
paramList.Add(new F1());
paramList.Add(new F2());
foreach (var p in paramList)
{
p.DoCommonOperation();
DoSpecificOperation(p);
}
Console.ReadKey();
}
private static void DoSpecificOperation(IParameter p)
{
if (p is F1)
{
(p as F1).F1Method();
}
else if (p is F2)
{
(p as F2).F2Method();
}
}
interface IParameter
{
void DoCommonOperation();
}
abstract class ParamBase : IParameter
{
public virtual void DoCommonOperation()
{
Console.WriteLine("ParamBase");
}
}
class FooParameter : ParamBase
{
public override void DoCommonOperation()
{
Console.WriteLine("FooParameter");
}
}
class BarParameter : ParamBase
{
public override void DoCommonOperation()
{
Console.WriteLine("BarParameter");
}
}
class F1 : FooParameter
{
public override void DoCommonOperation()
{
Console.WriteLine("F1");
}
public void F1Method()
{
Console.WriteLine("F1.F1Method");
}
}
class F2 : FooParameter
{
public override void DoCommonOperation()
{
Console.WriteLine("F2");
}
public void F2Method()
{
Console.WriteLine("F2.F2Method");
}
}
}
Essentially you have a method in the class that controls the list of IParameter objects that knows how to call the specific implementations, and uses is/as to do so.
Just for sanity's sake, why not use Dictionary<Type, IParameter>? With a little generics, you could do this:
public interface IParameter { }
public class FP12 : IParameter { public string fieldFP12 { get; set; } }
public class FP11 : IParameter { public string fieldFP11 { get; set; } }
public static class DictionaryHelper
{
public static T GetParameter<T>(this Dictionary<System.Type,
IParameter> target) where T : IParameter
{
return (T)target[typeof(T)];
}
}
Sample program and output:
class Program
{
static void Main()
{
Dictionary<Type, IParameter> parameters =
new Dictionary<Type, IParameter>();
parameters.Add(typeof(FP12), new FP12 { fieldFP12 = "This is FP12" });
parameters.Add(typeof(FP11), new FP11 { fieldFP11 = "This is FP11"});
// THIS IS WHERE YOU GET THE IPARAMETER YOU WANT - THE GENERICS WAY...
var fp12 = parameters.GetParameter<FP12>();
var fp11 = parameters.GetParameter<FP11>();
Console.WriteLine(fp12.fieldFP12);
Console.WriteLine(fp11.fieldFP11);
Console.ReadLine();
}
}
The resulting output:
This is FP12
This is FP11
In my console application have an abstract Factory class "Listener" which contains code for listening and accepting connections, and spawning client classes. This class is inherited by two more classes (WorldListener, and MasterListener) that contain more protocol specific overrides and functions.
I also have a helper class (ConsoleWrapper) which encapsulates and extends System.Console, containing methods for writing to console info on what is happening to instances of the WorldListener and MasterListener.
I need a way to determine in the abstract ListenerClass which Inheriting class is calling its methods.
Any help with this problem would be greatly appreciated! I am stumped :X
Simplified example of what I am trying to do.
abstract class Listener
{
public void DoSomething()
{
if(inheriting class == WorldListener)
ConsoleWrapper.WorldWrite("Did something!");
if(inheriting class == MasterListener)
ConsoleWrapper.MasterWrite("Did something!");
}
}
public static ConsoleWrapper
{
public void WorldWrite(string input)
{
System.Console.WriteLine("[World] {0}", input);
}
}
public class WorldListener : Listener
{
public void DoSomethingSpecific()
{
ConsoleWrapper.WorldWrite("I did something specific!");
}
}
public void Main()
{
new WorldListener();
new MasterListener();
}
Expected output
[World] Did something!
[World] I did something specific!
[Master] Did something!
[World] I did something specific!
If you know each of the types you want to compare against, then use the is operator:
if (this is WorldListener)
{
// ...
}
else if (this is MasterListener)
{
// ...
}
Alternatively, you could use GetType if you want a little more flexibility:
var type = GetType();
// Do some logic on the type to determine what to do next.
You should be careful with this approach, however; it's generally indicative of bad design that you need to explicitly check for types (as these lovely people insist). Instead, it's almost always more appropriate to use polymorphism to delegate the desired behaviour to the base class (using a virtual or abstract method in the base class) – this is, after all, what it's designed for!
You might apply polymorphism something like this:
static class Program
{
static void Main(string[] args)
{
Listener listener = new WorldListener();
listener.DoSomething();
}
}
abstract class Listener
{
public void DoSomething()
{
var output = Decorate("Did something!");
ConsoleWrapper.WriteLine(output);
}
protected abstract string Decorate(string input);
}
class WorldListener : Listener
{
protected override string Decorate(string input)
{
return string.Format("[World] {0}", input);
}
}
class MasterListener : Listener
{
protected override string Decorate(string input)
{
return string.Format("[Master] {0}", input);
}
}
This will produce the output [World] Did something!. The advantage of this approach is that if you ever want to add another type of listener, it's simply a matter of defining a new class for it with the appropriate Decorate method; there's no need to modify Listener itself.
You can use
if (this is WorldListener)
instead of your pseudocode
if (inheriting class == WorldListener)
However, doing this is a bad design smell. You should strongly consider an alternative solution, e.g. performing the write to the console wrapper in a virtual method instead of adding this strong coupling between the base class and its subclasses.
Hmm.. Well, in your simplified example you don't call DoSomething() and DoSomethingSpecific(), and there's no implementation for MasterListener..
Also, if I understand it right, in your expected output your MasterListener.DoSomethingSpecific() runs a ConsoleWrapper.WorldWrite.. You probably meanr MasterWrite?
In any case.. Here's a working example that does what you want (at least in the way I understood your request :P )
The printed result is:
[World] Did something
[World] I did sth specific!
[Master] Did something
[Master] I did sth specific!
The code:
void Main()
{
var wl = new WorldListener();
wl.DoSomething();
wl.DoSpecific();
var ml = new MasterListener();
ml.DoSomething();
ml.DoSpecific();
}
public abstract class Listener
{
public abstract string Category { get; }
public void DoSomething()
{
ConsoleWrapper.Write(Category, "Did something");
}
}
public static class ConsoleWrapper
{
public static void Write(string category, string input)
{
Console.WriteLine("[{0}] {1}", category, input);
}
}
public class WorldListener : Listener
{
public override string Category { get { return "World"; } }
public void DoSpecific()
{
ConsoleWrapper.Write(Category, "I did sth specific!");
}
}
public class MasterListener : Listener
{
public override string Category { get { return "Master"; } }
public void DoSpecific()
{
ConsoleWrapper.Write(Category, "I did sth specific!");
}
}