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.
Related
I've got the following interfaces:
public interface IObjectFinder<T> where T : IObject
{
Task<IObjectResults<T>> FindAsync(string name);
}
public interface IObject
{
string Id { get; }
}
I'd like to initialize a dictionary with the following:
this.finders = new Dictionary<string, IObjectFinder<IObject>>();
finders.Add("Car", new CarFinder<Car>());
finders.Add("Truck", new TruckFinder<Truck>());
Then create a simple controller method:
public async Task<IActionResult>(string objectType, string searchTerm)
{
if (!finders.TryGetValue(objectType, out var finder))
return NotFound();
var result = await finder.FindAsync(searchTerm);
return Ok(result);
}
The problem is the IObjectFinder<IObject> type of dictionary. A CarFinder<Car> isn't an IObjectFinder<IObject>. Is there an objectively better way to handle this? I'd like to avoid using MorseCode.ITask and dynamic's to avoid muddying up the code even more. How would you handle something like this?
After I thought some more, I think it's similar to how some generic interfaces (e.g. IEnumerator<T> and IEnumerator) are defined. We need to define some non-generic interfaces first:
public interface IObjectResults
{
}
public interface IObjectFinder
{
Task<IObjectResults> FindAsync(string name);
}
The generic interfaces need inherit them, and benefit from the default interface methods feature, we can implement them in this place.
public interface IObjectResults<T> : IObjectResults where T : IObject
{
}
public interface IObjectFinder<T> : IObjectFinder where T : IObject
{
new Task<IObjectResults<T>> FindAsync(string name);
async Task<IObjectResults> IObjectFinder.FindAsync(string name)
=> await FindAsync(name);
}
Now it's able to replace IObjectFinder<IObject> with IObjectFinder in the dictionary.
this.finders = new Dictionary<string, IObjectFinder>();
finders.Add("Car", new CarFinder());
var result = await finder.FindAsync(searchTerm);
I has interface
public interface ITest
{
Task<bool> MyMethod1<T>(string key, out T value);
Task<bool> MyMethod2<T>(string key, out T value);
}
And they implementation
public class TestImpl : ITest
{
public Task<bool> MyMethod1<T>(string key, out T value) // Implements interface
{
// Skipped
}
public Task<bool> MyMethod1<T>(string key, T value) // Does not implements interface
{
// Skipped
}
public Task<bool> MyMethod2<T>(string key, out T value) // Implements interface
{
// Skipped
}
public Task<bool> MyMethod2<T>(string key, T value) // Does not implements interface
{
// Skipped
}
}
I need to check that specified instance of MethodInfo is method implementation of ITest interface.
For example:
void DoWork(MethodInfo methodInfo)
{
if (...) // Check methodInfo is implementation of any method declared in ITest interface
{
/* Do something */
}
}
How to do that?
I have an idea, but I don't know if it fits your situation
Why you don't get type of the implementation the class and then you get the interface you are interested in by its name nameof(ITest) and then you iterate through all methods of this interface which is implemented by that type like the following:
foreach(var methodInfo in typeof(TestImpl).GetInterface(nameof(ITest)).GetMethods())
{
}
This is very easy idea, the fact that you didn't hard-coded the interface name in the foreach loop it is good too.
If it didn't fit your situation, please consider adding more details to your question so I can think about a different idea and edit this answer, or someone can help you.
EDIT
Or you can get the concrete class type by the property ReflectedType and then you can get a 'reflection-mapping' of the methods of this type based on specific interface type using GetInterfaceMap method, this method will then returns the methods which is implemented for this interface type in this concrete class type, you can then simply use the method Contains to check for specific MethodInfo instance as you asked. Hope this helped you now.
static bool IsMethodImplementationOfInterface(Type interfaceType,MethodInfo method)
{
return method.ReflectedType.GetInterfaceMap(interfaceType).TargetMethods.Contains(method);
}
foreach (var methodInfo in typeof(TestImpl).GetMethods())
{
if (IsMethodImplementationOfInterface(typeof(ITest), methodInfo))
{
//Logic
}
}
You can use GetInterfaceMap:
var testImpl = new TestImpl();
var interfaceTargeMethods = testImpl.GetType().GetInterfaceMap(typeof(ITest)).TargetMethods;
foreach (var methodInfo in testImpl.GetType().GetMethods())
{
if (interfaceTargeMethods.Contains(methodInfo))
{
// do something...
}
}
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.
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.
I am trying to port some code I wrote in C# to Java, but do not know all of the Java syntax yet. I also have no idea what this type of thing is called, so it is harder to search..I am calling it "inheritance constraints."
Basically, is there a java equivalent to this C# code:
public abstract class MyObj<T> where T : MyObj<T>, new()
{
}
Thanks.
Edit:
Is there any way to do this:
public abstract class MyObj<T extends MyObj<T>> {
public abstract String GetName();
public virtual void Test() {
T t = new T(); // Somehow instantiate T to call GetName()?
String name = t.GetName();
}
}
Not quite. There's this:
public abstract class MyObj<T extends MyObj<T>>
but there's no equivalent to the new() constraint.
EDIT: To create an instance of T, you'll need the appropriate Class<T> - otherwise type erasure will byte you.
Typically you'd add this as a constructor parameter:
public MyObj(Class<T> clazz) {
// This can throw all kinds of things, which you need to catch here or
// propagate.
T t = clazz.newInstance();
}
Judging by your comment above, you're looking for the following construct:
An interface with which you will interact with MyObj objects in code... you will be calling the test() method (standard style in Java is camelcase methods, capitalized classes/interfaces)
public interface IMyObj {
public void test();
}
You will want the abstract superclass... for the example that you've chosen, you don't NEED to specify any genericism, although you absolutely can if the actual implementation is more reliant on type safety... this class should implement the IMyObj interface:
public abstract class MyObj implements IMyObj {
String name;
public abstract String getName();
public void test() {
name = getName();
}
}
From here you would write your subclasses to MyObj...
public class MySubObj1 extends MyObj {
public String getName() { return "MySubObj1"; }
}
public class MySubObj2 extends MyObj {
public String getName() { return "MySubObj2"; }
}
Then you safely and correctly use the following snippet in another class:
IMyObj obj = new MySubObj1();
obj.test();
The key is that you use interfaces to hide the implementation, and use abstract classes to hold common code that subclasses will utilize in their implementations.
Hope this helps!