如何使用"myFunc(Func<T>) where T : class"以及"myFunc(Func<bool>)"实现相同的接口?



背景:

为了去除多余的代码,我使用了策略模式。因此,我将这个(前一个(冗余代码放入策略模式的上下文类中,其中将调用方法IsSuccess ProcessApiMethod((。上下文类不是我的问题所在,我只是为了完整性向您展示它。

难度:

如果TOut是一个类,
  • 方法ProcessApiMethod((应返回null
  • 但是TOut也可以是像int或bool这样的基本类型

到目前为止已解决:

  • 此外,某些API方法将具有返回类型void。这就是我实现两个不同接口的原因

我的问题-困难在于:

  • C#是否允许替代通用约束
  • 如何允许基本类型作为T的可能类型

我错过了以下内容。。。

public interface ISuccessConverterStrategy<TOut> where Tout : (class || basicType)

但这毫无意义:

public interface ISuccessConverterStrategy<TOut> where Tout : (class || (!class && !struct))
  • 如果"否";是你对我第一个问题的回答:我该如何解决这个问题

目前,无论我如何尝试,在我的策略类中,编译器告诉我">接口成员"TOut SuccessConverter.ISuccessConverterStrategie.GetResult(("未实现"或者他提到了使用这些泛型的另一个问题。

这是我完整的代码:

public enum IsSuccess
{
No = - 1,
NotSupported = 0,
Yes = 1,
WithoutContent = 2
}
/// <sumary>
/// Interface of Strategy Pattern
/// </summary>
public interface ISuccessConverterStrategy
{
IsSuccess ProcessApiMethod();
}

public interface ISuccessConverterStrategy<TOut> : ISuccessConverterStrategy
{
/// <summary>
/// After processing 
/// Returns null, if processing method has no return value.
/// Returns null, if something went wrong.
/// Returns return value, otherwise.
/// </summary>
/// <typeparam name="TOut"></typeparam>
/// <returns></returns>
TOut GetResult<TOut>();
}
/// <summary>
/// Context class of strategy pattern.
/// </summary>
public class SilentSuccessConverter
{
/// <summary>
/// Silences API-method when called within strategy-method. Extends range of possible return values
/// of type IsSuccess, e.g. by IsSuccess.NotSupported. Catches possible exception messages.
/// </summary>
/// <param name="strategy"></param>
/// <param name="errorMessage"></param>
/// <returns></returns>
/// <exception cref="NullReferenceException"></exception>
public IsSuccess Convert(ISuccessConverterStrategy strategy, out string errorMessage)
{
if (null == strategy)
{
throw new NullReferenceException(nameof(strategy));
}
errorMessage = "";
try
{
return strategy.ProcessApiMethod();
}
catch (Exception e) when (e.Message.ToLower().Contains("not implemented"))
{
errorMessage = $" - Message: {e.Message} - Source: {e.Source}" + Environment.NewLine;
return IsSuccess.NotSupported;
}
catch (Exception e)
{
errorMessage = $" - Message: {e.Message} - Source: {e.Source}" + Environment.NewLine;                

if (e is NotImplementedException || e is NotSupportedException)
{
return IsSuccess.NotSupported;
}

return IsSuccess.No;
}
}   
}
public class FuncTOutClassStrategy<TOut> : ISuccessConverterStrategy<TOut> where TOut : class
{
private Func<TOut> _apiMethod;
private TOut _result;
/// <summary>
/// Holds a method without parameters, which returns an generic class object.
/// </summary>
/// <param name="apiMethod"></param>
public void SetApiMethod(Func<TOut> apiMethod)
{
_apiMethod = apiMethod ?? throw new NullReferenceException(nameof(apiMethod));
}

public IsSuccess ProcessApiMethod()
{
_result = _apiMethod();
return null != _result ? IsSuccess.Yes : IsSuccess.No; 
}
public TOut GetResult()
{
return _result;
}
}
public class FuncIntOutStrategy<int> : ISuccessConverterStrategy<int> 
{
private Func<int> _apiMethod;
private int _result;
/// <summary>
/// Holds a method without parameters, which returns int.
/// </summary>
/// <param name="apiMethod"></param>
public void SetApiMethod(Func<int> apiMethod)
{
_apiMethod = apiMethod ?? throw new NullReferenceException(nameof(apiMethod));
}

public IsSuccess ProcessApiMethod()
{
_result = _apiMethod();
return _result > 0 ? IsSuccess.Yes : IsSuccess.No; 
}
public int GetResult()
{
return _result;
}
}
public class ActionTInStrategy<TIn> : ISuccessConverterStrategy 
{
private Action<TIn> _apiMethod;
private TIn _input;
/// <summary>
/// Holds a void method that receives an object of type T.
/// </summary>
/// <param name="apiMethod"></param>
/// <param name="input"></param>
public void SetApiMethod(Action<TIn> apiMethod, TIn input)
{
_input = input;
_apiMethod = apiMethod ?? throw new NullReferenceException(nameof(apiMethod));
}
public IsSuccess ProcessApiMethod()
{
_apiMethod(_input);
return  IsSuccess.Yes; 
}
}
public class ActionStrategy : ISuccessConverterStrategy
{
private Action _apiMethod;
/// <summary>
/// Holds a void method without any parameters.
/// </summary>
/// <param name="apiMethod"></param>
public void SetApiMethod(Action apiMethod)
{
_apiMethod = apiMethod ?? throw new NullReferenceException(nameof(apiMethod));
}
public IsSuccess ProcessApiMethod()
{
_apiMethod();
return  IsSuccess.Yes; 
}
}

现在我想我得到它没有错误。这些是我修改的代码部分:

public interface ISuccessConverterStrategy<out TOut> : ISuccessConverterStrategy 
{
/// <summary>
/// After processing 
/// Returns null, if processing method has no return value.
/// Returns null, if something went wrong.
/// Returns return value, otherwise.
/// </summary>
/// <typeparam name="TOut"></typeparam>
/// <returns></returns>
TOut GetResult();
}
public class FuncBoolOutStrategy : ISuccessConverterStrategy<bool>
{
private Func<bool> _apiMethod;
private bool _result;
/// <summary>
/// Holds a method without parameters, which returns bool.
/// </summary>
/// <param name="apiMethod"></param>
public void SetApiMethod(Func<bool> apiMethod)
{
_apiMethod = apiMethod ?? throw new NullReferenceException(nameof(apiMethod));
}

public IsSuccess ProcessApiMethod()
{
_result = _apiMethod();
return _result ? IsSuccess.Yes : IsSuccess.No; 
}
public bool GetResult()
{
return _result;
}
}
public class FuncIntOutStrategy : ISuccessConverterStrategy<int> 
{
private Func<int> _apiMethod;
private int _result;
/// <summary>
/// Holds a method without parameters, which returns int.
/// </summary>
/// <param name="apiMethod"></param>
public void SetApiMethod(Func<int> apiMethod)
{
_apiMethod = apiMethod ?? throw new NullReferenceException(nameof(apiMethod));
}

public IsSuccess ProcessApiMethod()
{
_result = _apiMethod();
return _result > 0 ? IsSuccess.Yes : IsSuccess.No; 
}
public int GetResult()
{
return _result;
}
}
public class FuncTOutClassStrategy<TOut> : ISuccessConverterStrategy<TOut>  where TOut : class
{
private Func<TOut> _apiMethod;
private TOut _result;
/// <summary>
/// Holds a method without parameters, which returns an generic class object.
/// </summary>
/// <param name="apiMethod"></param>
public void SetApiMethod(Func<TOut> apiMethod)
{
_apiMethod = apiMethod ?? throw new NullReferenceException(nameof(apiMethod));
}

public IsSuccess ProcessApiMethod()
{
_result = _apiMethod();
return null != _result ? IsSuccess.Yes : IsSuccess.No; 
}
public TOut GetResult()
{
return _result;
}
}

也许你发现了一些需要改进的地方,比如必要的约束或。

相关内容

  • 没有找到相关文章

最新更新