So I was trying to make a simple awaitable struct that allow my to return a bool:
// define a special container for returning results
public struct BoolResult {
public bool Value;
public BoolAwaiter GetAwaiter () {
return new BoolAwaiter(Value);
}
}
// make the interface task-like
public readonly struct BoolAwaiter : INotifyCompletion {
private readonly bool _Input;
// wrap the async operation
public BoolAwaiter (bool value) {
_Input = value;
}
// is task already done (yes)
public bool IsCompleted {
get { return true; }
}
// wait until task is done (never called)
public void OnCompleted (Action continuation) => continuation?.Invoke();
// return the result
public bool GetResult () {
return _Input;
}
}
And I was using it like:
private async BoolResult LoadAssets (string label) {
//
// some await asyncFunction here
//
// then at the end
return new BoolResult { Value = true };
}
But I still get this compile error:
error CS1983: The return type of an async method must be void, Task or Task<T>
I thought my BoolResult was already Task-like? What's the issue here?
Related
I am working on implementing pub/sub pattern for cache use. The following class is suppose to be used to publish any type of data. And subscribers can attach a callback of Action T on the event. But I couldn't create a generic event at the class level without making the class generic and I don't want to do that. So I have tried to cast the values back and forth to string using JsonSerializer as follows.
public class CacheNotification
{
public Action<string> CachePublished;
public Task Publish<T>(T value)
{
var json = JsonSerializer.Serialize(value);
OnCachePublished(json);
return Task.CompletedTask;
}
public Task Subscribe<T>(Action<T> callback)
{
Action<string> newCallback = (string json) =>
callback(JsonSerializer.Deserialize<T>(json));
CachePublished += newCallback;
return Task.CompletedTask;
}
protected virtual void OnCachePublished(string value)
{
if(CachePublished != null){
CachePublished.Invoke(value);
}
}
}
So the problem is on the subscribe method, the casting I attempted only works for Action string. It fails on Action int or Action object
public Task Subscribe<T>(Action<T> callback)
{
Action<string> newCallback = (string json) =>
callback(JsonSerializer.Deserialize<T>(json));
CachePublished += newCallback;
return Task.CompletedTask;
}
Here is a test I used. This fails for second subscriber
Action<string> sub1Callback = msg =>
{
sub1Counter++;
};
Action<int> sub2Callback = num =>
{
sub2Counter++;
};
var sub1 = await cache.Subscribe(sub1Callback);
var sub2 = await cache.Subscribe(sub2Callback);
await cache.Publish("Value1");
Assert.Equal(1, sub1Counter);
Assert.Equal(1, sub2Counter);
your problem is here:
Action sub2Callback = num =>
after
await cache.Publish("Value1");
Your:
public Task Subscribe<T>(Action<T> callback)
{
Action<string> newCallback = (string json) => callback(JsonSerializer.Deserialize<T>(json));
CachePublished += newCallback;
return Task.CompletedTask;
}
tries to deserialize "Value1" to integer and it correctly fails. It cannot be done.
Try to send integer value instead of "Value1" and it should work.
Another way is to refactor your Subscribe method to be independent of given type, but this cannot be done according to your intentions I guess.
A function that returns a value:
public object ReturnValue() { return new object(); }
Func<object> funcReturnValue = ReturnValue;
A function that retuns a function that returns a value:
public Func<object> ReturnFunc() { return ReturnValue; }
Func<Func<object>> funcReturnFunc = ReturnFunc;
So far, so good. I'm having trouble with a function that returns itself:
public *something* ReturnSelf() { return ReturnSelf; }
Func<*something*> funcReturnSelf = ReturnSelf;
Clearly, *something* is going to be a Func<T> of some kind, but I'm not sure what.
At first glance I guess it's going to be infinity recursive, since ReturnSelf
returns a function that returns a function that returns a function...
Context: A state machine using functions for states. It works fine using
a class variable to keep the current state:
private Action _currentState;
private void StateOne() {
if (IsTuesday) {
_currentState = StateTwo;
}
}
prvivate void StateTwo() {
if (IsRaining) {
_currentState = StateOne;
}
}
private void StateEngine() {
while (true) {
_currentState();
// set tuesday/raining/etc.
}
}
...but that feels too much like keeping state in a global.
I'd far prefer something closer to:
private Func<*somthing*> StateOne() {
if (IsTuesday) {
return StateTwo;
} else {
return StateOne;
}
}
prvivate Func<*something*> StateTwo() {
if (IsRaining) {
return StateOne;
} else {
return StateTwo;
}
}
private void StateEngine() {
Func<*something*> currentState = StateOne;
while (true) {
Func<*something*> nextState = currentState();
// set tuesday/raining/etc.
currentState = nextState;
}
}
Any ideas? Or should I just stick with the working solution?
Instead of using Func<T> you could define a delegate which returns a value of that delegate type. Delegates can be used to pass function references as arguments to another function, or in this case to return a function reference from a function (docs).
Example:
class Program
{
private delegate StateDelegate StateDelegate();
public static void Main(string[] args)
{
Program program = new Program();
StateDelegate stateHandler = program.HandleStateOne;
// Execute HandleStateOne, returns HandleStateTwo
stateHandler = stateHandler.Invoke();
// Execute HandleStateTwo, returns reference to HandleStateOne
stateHandler = stateHandler.Invoke();
}
private StateDelegate HandleStateOne()
{
// Do something state specific...
return HandleStateTwo;
}
private StateDelegate HandleStateTwo()
{
// Do something state specific...
return HandleStateOne;
}
// Literally return reference to the function itself
private StateDelegate ReturnSelf()
{
return ReturnSelf;
}
}
You can do this with the help of an extra type:
class State
{
private Func<State> _func;
public State(Func<State> func)
{
_func = func;
}
public State Invoke() => _func();
}
And then you can write:
bool IsTuesday = false;
bool IsRaining = false;
State StateOne = null;
State StateTwo = null;
StateOne = new State
(
() =>
{
if (IsTuesday) {
return StateTwo;
} else {
return StateOne;
}
}
);
StateTwo = new State
(
() =>
{
if (IsRaining) {
return StateOne;
} else {
return StateTwo;
}
}
);
And, of course:
void StateEngine() {
State currentState = StateOne;
while (true) {
var nextState = currentState.Invoke();
// set tuesday/raining/etc.
currentState = nextState;
}
}
We may do a little more, with an implicit conversion to Func<State> (and then you don't need an invoke method anymore):
public static implicit operator Func<State> (State state)
{
return state._func;
}
Then you can write:
void StateEngine() {
Func<State> currentState = StateOne;
while (true) {
Func<State> nextState = currentState();
// set tuesday/raining/etc.
currentState = nextState;
}
}
So, Func<State> returns something that can be converted implicitly into Func<State>.
Code in SharpLap
I'm trying to apply Specification pattern to my validation logic. But I have some problems with async validation.
Let's say I have an entity AddRequest (has 2 string property FileName and Content) that need to be validated.
I need to create 3 validators:
Validate if FileName doesn't contains invalid characters
Validate if Content is correct
Async validate if file with FileName is exists on the database. In this case I should have something like Task<bool> IsSatisfiedByAsync
But how can I implement both IsSatisfiedBy and IsSatisfiedByAsync? Should I create 2 interfaces like ISpecification and IAsyncSpecification or can I do that in one?
My version of ISpecification (I need only And)
public interface ISpecification
{
bool IsSatisfiedBy(object candidate);
ISpecification And(ISpecification other);
}
AndSpecification
public class AndSpecification : CompositeSpecification
{
private ISpecification leftCondition;
private ISpecification rightCondition;
public AndSpecification(ISpecification left, ISpecification right)
{
leftCondition = left;
rightCondition = right;
}
public override bool IsSatisfiedBy(object o)
{
return leftCondition.IsSatisfiedBy(o) && rightCondition.IsSatisfiedBy(o);
}
}
To validate if file exists I should use:
await _fileStorage.FileExistsAsync(addRequest.FileName);
How can I write IsSatisfiedBy for that check if I really need do that async?
For example here my validator (1) for FileName
public class FileNameSpecification : CompositeSpecification
{
private static readonly char[] _invalidEndingCharacters = { '.', '/' };
public override bool IsSatisfiedBy(object o)
{
var request = (AddRequest)o;
if (string.IsNullOrEmpty(request.FileName))
{
return false;
}
if (request.FileName.Length > 1024)
{
return false;
}
if (request.FileName.Contains('\\') || _invalidEndingCharacters.Contains(request.FileName.Last()))
{
return false;
}
return true
}
}
I need to create FileExistsSpecification and use like:
var validations = new FileNameSpecification().And(new FileExistsSpecification());
if(validations.IsSatisfiedBy(addRequest))
{ ... }
But how can I create FileExistsSpecification if I need async?
But how can I implement both IsSatisfiedBy and IsSatisfiedByAsync? Should I create 2 interfaces like ISpecification and IAsyncSpecification or can I do that in one?
You can define both synchronous and asynchronous interfaces, but any general-purpose composite implementations would have to only implement the asynchronous version.
Since asynchronous methods on interfaces mean "this might be asynchronous" whereas synchronous methods mean "this must be synchronous", I'd go with an asynchronous-only interface, as such:
public interface ISpecification
{
Task<bool> IsSatisfiedByAsync(object candidate);
}
If many of your specifications are synchronous, you can help out with a base class:
public abstract class SynchronousSpecificationBase : ISpecification
{
public virtual Task<bool> IsSatisfiedByAsync(object candidate)
{
return Task.FromResult(IsSatisfiedBy(candidate));
}
protected abstract bool IsSatisfiedBy(object candidate);
}
The composites would then be:
public class AndSpecification : ISpecification
{
...
public async Task<bool> IsSatisfiedByAsync(object o)
{
return await leftCondition.IsSatisfiedByAsync(o) && await rightCondition.IsSatisfiedByAsync(o);
}
}
public static class SpecificationExtensions
{
public static ISpecification And(ISpeicification #this, ISpecification other) =>
new AndSpecification(#this, other);
}
and individual specifications as such:
public class FileExistsSpecification : ISpecification
{
public async Task<bool> IsSatisfiedByAsync(object o)
{
return await _fileStorage.FileExistsAsync(addRequest.FileName);
}
}
public class FileNameSpecification : SynchronousSpecification
{
private static readonly char[] _invalidEndingCharacters = { '.', '/' };
public override bool IsSatisfiedBy(object o)
{
var request = (AddRequest)o;
if (string.IsNullOrEmpty(request.FileName))
return false;
if (request.FileName.Length > 1024)
return false;
if (request.FileName.Contains('\\') || _invalidEndingCharacters.Contains(request.FileName.Last()))
return false;
return true;
}
}
Usage:
var validations = new FileNameSpecification().And(new FileExistsSpecification());
if (await validations.IsSatisfiedByAsync(addRequest))
{ ... }
I don't know, why you need async operations in a sync driven pattern.
Imagine, if the first result is false and you have two or more async checks, it would be a waste in performance.
If you want to know, how to get an async request back in sync, you can try to use the following:
public class FileExistsSpecification : CompositeSpecification
{
public override bool IsSatisfiedBy(object o)
{
var addRequest = (AddRequest)o
Task<bool> fileExistsResult = _fileStorage.FileExistsAsync(addRequest.FileName);
fileExistsResult.Wait();
return fileExistsResult.Result;
}
}
You should also use the generics approach.
I think your main goal here is to make sure that code finishes as soon as possible for evaluating a composite specification, when executing child specifications and one or more may take a while, yes? It's always possible for calling code outside of your pattern implementation to invoke a specification asynchronously; it's not really your concern at that point.
So, in light of that, how about giving your ISpecification an extra property?
public interface ISpecification
{
bool IsAsynchronous { get; }
bool IsSatisfiedBy(object o);
}
Then, for non-composite synchronous or asynchronous-type specifications, hard-code the return value for IsAsynchronous. But in composite ones, base it on the children, to wit:
public class AndSpecification : ISpecification
{
private ISpecification left;
private ISpecification right;
public AndSpecification(ISpecification _left, ISpecification _right)
{
if (_left == null || _right == null) throw new ArgumentNullException();
left = _left;
right = _right;
}
public bool IsAsynchronous { get { return left.IsAsynchronous || right.IsAsynchronous; }
public override bool IsSatisfiedBy(object o)
{
if (!this.IsAsynchronous)
return leftCondition.IsSatisfiedBy(o) && rightCondition.IsSatisfiedBy(o);
Parallel.Invoke(
() => {
if (!left.IsSatisfiedBy(o)) return false;
},
() => {
if (!right.IsSatisfiedBy(o)) return false;
}
);
return true;
}
}
But taking this a bit further, you don't want to waste performance. Hence why not evaluate the fast, synchronous child first when there's one sync and one async? Here's a closer-to-finished version of the basic idea:
public class AndSpecification : ISpecification
{
private ISpecification left;
private ISpecification right;
public AndSpecification(ISpecification _left, ISpecification _right)
{
if (_left == null || _right == null) throw new ArgumentNullException();
left = _left;
right = _right;
}
public bool IsAsynchronous { get { return left.IsAsynchronous || right.IsAsynchronous; }
public override bool IsSatisfiedBy(object o)
{
if (!left.IsAsynchronous)
{
if (!right.IsAsynchronous)
{
return left.IsSatisfiedBy(o) && right.IsSatisfiedBy(o);
}
else
{
if (!left.IsSatisfiedBy(o)) return false;
return right.IsSatisfiedBy(o);
}
}
else if (!right.IsAsynchronous)
{
if (!right.IsSatisfiedBy(o)) return false;
return left.IsSatisfiedBy(o);
}
else
{
Parallel.Invoke(
() => {
if (!left.IsSatisfiedBy(o)) return false;
},
() => {
if (!right.IsSatisfiedBy(o)) return false;
}
);
return true;
}
}
}
I would like to introduce a method/function which can receive an Action or a Func<T>, and depending on what it got, it should return void or T.
Now I have to write this method in two, almost same versions like this.
public void WrapAction(Action action) {
// do something...
action();
// do something more...
}
public T WrapFunc(Func<T> func) {
// do something...
var result = func();
// do something more...
return result;
}
Is there any technique to avoid this repetition?
In contrast, for example in Javascript I have the flexibility to accept any kind of a function (may be void) and just return it's result, and if it was void, then it will return undefined. But in C# one cannot write something like Func<void>.
What about to make an Func<bool> out of an action via an extension method and reduce the wrapper to handle Func<T> only.
public static class ActionExtensions
{
public static Func<bool> ToFunc(this Action action)
{
return () =>
{
action();
return true;
};
}
}
Then WrapAction could simply call WrapFunc.
public void WrapAction(Action action)
{
WrapFunc(action.ToFunc());
}
Or remove WrapAction at all and use WrapFunc directly.
WrapFunc(action.ToFunc());
One possible solution is that you can extract the repeating bits out to separate methods in the same class so, something like this...
public void WrapAction(Action action) {
DoInitialBit();
action();
DoFinalBit();
}
public T WrapFunc(Func<T> func) {
DoInitialBit();
var result = func();
DoFinalBit();
return result;
}
private void DoInitialBit()
{
// Do the thing before you call the Action or Func
}
private void DoFinalBit()
{
// Do the thing after you call the Action or Func
}
Obviously, you may have to take inputs or return outputs from these additional methods as required but that's the general gist of it.
Some really ugly code to have code DRY:
static void Main(string[] args)
{
var p = new Program();
p.WrapAction(() => Console.WriteLine(123));
Console.WriteLine(p.WrapFunc<string>(() => "321"));
Console.ReadKey();
}
public void WrapAction(Action action) => WrapActionInner<object>(action);
public T WrapFunc<T>(Func<T> func) => WrapActionInner<T>(func);
private T WrapActionInner<T>(object action)
{
if (action is Action)
{
((Action)action)();
return default(T);
}
return ((Func<T>)action)();
}
The idea is to wrap functionality into type unsafe private method.
I would like to provide encapsulation of actions/methods generically. I think this should be possible in C# but I'm not able to produce it so it compiles...
The following briefly demonstrates what I want. Is this possible somehow, perhaps by generalizing the class?
Required is:
I want to execute the function/action (see method type) and 'do something' when an error occurs
I want to return the value of the function if the method is a function (otherwise return void if possible)
I want to 'do something' if the return type of the function is a boolean and the value is false.
public class Encapsulator {
private Action _action;
private Func<T> _function;
private MethodType _type; //Action || Function
public Encapsulator(Action action) {
this._action = action;
this._type = MethodType.Action;
}
public Encapsulator(Func<T> func) { //This is not accepted
this._function = func;
this._type = MethodType.Function;
}
public void Execute() {
try {
this._action();
}
catch(Exception ex) {
//do something
throw;
}
}
public T Execute<T>() {
try {
var r = this._function();
if(typeof(r) == bool) {
if(!r)
//do something
}
return r;
} catch(Exception ex) {
//do something
throw;
}
}
}
Your second constructor won't compile because their are no generics applied to the type at the higher level:
public Encapsulator<T>
{
public Encapsulator(Func<T> func)
{
this._function = func;
this._type = MethodType.Function;
}
}
Instead of just introducing new things within the parameters of a method, essentially, we need to specify that those things are 'available' for utilisation in the definitions. So, for instance, if you were trying to add a specific generic method, you could apply it as you have done, but would instead need to do (something which you demonstrate with the Execute method):
public void MyGenericMethod<T>(Func<T> func)
{
}
Noting the first T, we're specifying the existence of T, as such.
There are possibly more issues at hand with your code here, but I believe, on first glance, this to be the crux of the problems you're having.
As for returning variable types, the best you might hope for is returning a plain old object. Or, making use of the dynamic type, however, I wouldn't have thought this would be the way to go and wouldn't recommend it; you can't flip return type from an actual type to a void, though.
New Approach: The action Encapsulator will now return a dummy result (always true).
public class Encapsulator
{
public static Encapsulator<bool> CreateEncapsulator(Action action)
{
return new Encapsulator<bool>(() =>
{
action();
return true;
});
}
public static Encapsulator<T> CreateEncapsulator<T>(Func<T> func)
{
return new Encapsulator<T>(func);
}
}
public class Encapsulator<T>
{
private Func<T> _function;
internal Encapsulator(Func<T> func)
{
this._function = func;
}
public T Execute()
{
try
{
object res = this._function();
Nullable<bool> bres = res as Nullable<bool>;
if (bres.HasValue)
{
if (!bres.Value)
Console.WriteLine("NOT TRUE!");
//do something
}
return (T)res;
}
catch (Exception ex)
{
//do something
throw;
}
}
}
Calling the code:
var withDummyReturn = Encapsulator.CreateEncapsulator(() => Console.WriteLine("Great"));
withDummyReturn.Execute();
var withReturn = Encapsulator.CreateEncapsulator<bool>(() => true);
bool res = withReturn.Execute();