-
-
Save dimitris-papadimitriou-chr/578f76c2d4b8d18f6f7fc8e69dcf0153 to your computer and use it in GitHub Desktop.
C# Covarinace and what has to do with Functional C#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Threading.Tasks; | |
namespace FunctionalExperimentation.Practical.FuncTaskCovarinat | |
{ | |
public static partial class F | |
{ | |
public static IFuncTask<T> ToWithResult<T>(this Func<Task<T>> @this) => new FuncTaskAdapter<T>(@this); | |
public static T GetOrThrowIfNull<T>(this IFuncTask<T> @this, string message) | |
{ | |
var value = @this.GetResult(); // this might also throw exception from Task. | |
return value ?? throw new Exception(message); | |
} | |
public static T GetOrThrow<T>(this IFuncTask<T> @this, string message) | |
{ | |
try | |
{ | |
return @this.GetOrThrowIfNull(message); | |
} | |
catch (Exception e) //Please Dont hide Exceptions | |
{ | |
throw new Exception(message); | |
} | |
} | |
} | |
public interface IWithSuccess | |
{ | |
public bool IsSuccessful { get; } | |
} | |
public class SomeResult : IWithSuccess | |
{ | |
public bool IsSuccessful => true; | |
} | |
public class FuncTaskCovarinat | |
{ | |
public static async Task RunAsync() | |
{ | |
Func<Task<SomeResult>> GetSomethingLazyAsync() => () => Task.FromResult(new SomeResult()); | |
//Func<Task<IWithResult>> t = GetSomethingLazyAsync(); | |
//Error CS0029 Cannot implicitly convert type 'System.Func<System.Threading.Tasks.Task<FunctionalExperimentation.Practical.FuncTaskCovarinat.SomeResult>>' | |
// to 'System.Func<System.Threading.Tasks.Task<FunctionalExperimentation.Practical.FuncTaskCovarinat.IWithResult>>' | |
//ok this is covariant on T | |
IFuncTask<IWithSuccess> lazyResult = GetSomethingLazyAsync() | |
.ToWithResult(); | |
SomeResult result = GetSomethingLazyAsync() | |
.ToWithResult() | |
.GetOrThrow("failed to get"); | |
} | |
public static async Task RunAsyncClassic() | |
{ | |
Func<Task<SomeResult>> GetSomethingLazyAsync() => () => Task.FromResult(new SomeResult()); | |
SomeResult result; | |
var lazyTask = GetSomethingLazyAsync(); | |
result = await lazyTask(); | |
if (result is null) | |
throw new Exception("failed to get Anything"); | |
} | |
public static async Task RunAsyncClassicExtendedWithTryCatch() | |
{ | |
Func<Task<SomeResult>> GetSomethingLazyAsync() => () => Task.FromResult(new SomeResult()); | |
SomeResult result; | |
try | |
{ | |
var lazyTask = GetSomethingLazyAsync(); | |
result = await lazyTask(); | |
if (result is null) | |
throw new Exception("failed to get Anything"); | |
} | |
catch (Exception e) //Please Dont hide Exceptions | |
{ | |
throw new Exception("failed to get Anything"); | |
} | |
} | |
} | |
public interface IFuncTask<out T> | |
{ | |
T GetResult(); | |
} | |
public class FuncTaskAdapter<T> : IFuncTask<T> | |
{ | |
public Func<Task<T>> Unwrap() => funcTask; | |
private readonly Func<Task<T>> funcTask; | |
public FuncTaskAdapter(Func<Task<T>> funcTask) => | |
this.funcTask = funcTask; | |
public T GetResult() => funcTask().Result; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment