using System;
using System.Reflection;
using System.Threading.Tasks;
using System.Linq;
namespace Invoker
{
public static class MethodExtension
{
public static async Task<dynamic> InvokeAsync(this MethodInfo @this, object obj, params object[] parameters)
{
//あらゆる関数をタスク化する。
dynamic awaitable = @this.Invoke(obj, parameters);
if (isNonTask(@this) && awaitable != null) return awaitable;
if (isNonTask(@this)) return true;
await awaitable;
if (isVoidTask(@this)) return true;
return awaitable.GetAwaiter().GetResult();
}
static bool isNonTask(MethodInfo m)
{
var ch = typeof(Task).ToString();
if (m.ReturnType.ToString().IndexOf(ch) == -1) return true;
return false;
}
static bool isVoidTask(MethodInfo m)
{
var ch = typeof(Task).ToString();
if (m.ReturnType.ToString() == ch) return true;
return false;
}
}
public static class StringExtension{
public static int ToInt(this string @this,int falseValue=-1){
var d = @this.ToDecimal((decimal) falseValue);
return (int)d;
}
public static float ToFloat(this string @this, float falseValue = -1)
{
var d = @this.ToDecimal((decimal)falseValue);
return (float)d;
}
public static bool ToBool(this string @this, bool falseValue=false)
{
var wk = falseValue==true?1:0;
var d = (int)@this.ToDecimal((decimal)wk);
return (d==1)?true:false;
}
public static decimal ToDecimal(this string @this,decimal falseValue=-1){
if (decimal.TryParse(@this, out decimal ret)) return ret;
else return falseValue;
}
}
public class CmdLine<T> where T : new()
{
T obj = new();
Type objType = typeof(T);
char sep = ' ';
public async Task<dynamic> cmdline(string str)
{
var ary = str.Split(sep);
var cmd = ary.First();
var fn = objType.GetMethod(cmd);
if (fn == null) return false;
var max = fn.GetParameters().Length;
var args = Enumerable.Repeat("", max).ToArray();//引数分用意
var _args = ary.Skip(1).Take(max).ToArray();
for (var i = 0; i < _args.Length; i++) args[i] = _args[i];
return await fn.InvokeAsync(obj, args);
}
}//class CmdLine
}//
namespace program
{
using Invoker;
public class wrapper{
public void random(string x){ //文字列から受け取るため引数は文字列のみ。
//random 100
var r=new Random();
var ret=x.ToInt(10);
ret=r.Next(0,ret);
Console.WriteLine(ret);
}
public async Task wait(string time){
//wait 100
var ret =time.ToInt(0);
await Task.Delay(ret);
}
public async Task<int> sum(string a,string b){
//sum 100 99
var _a=a.ToInt(0);
var _b=b.ToInt(0);
await wait(""+1000);
return _a+_b;
}
public void dummy(){
//dummy
Console.WriteLine("dummy");
}
}//class
class Program
{
static async Task Main(string[] args)
{
var x=new CmdLine<wrapper>();
await x.cmdline("random 100");
await x.cmdline("random");//less args
await x.cmdline("random 100 100 999 111");//too much args
await x.cmdline("wait 1000");
var ret=await x.cmdline("sum 100 99");
int t = ret + 5;
await x.cmdline("dummy aaa");
await x.cmdline("dummyxyz");//notfound method
Console.WriteLine("Hello World!");
}
}
}