Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 编程到具有所需参数值的接口_C#_Interface_Abstract_Requirements - Fatal编程技术网

C# 编程到具有所需参数值的接口

C# 编程到具有所需参数值的接口,c#,interface,abstract,requirements,C#,Interface,Abstract,Requirements,我想从某种存储器中获取统计信息。因为我希望能够切换存储,所以我希望使用一个接口和程序来切换存储 不过,我需要对实现提出一些要求,比如只接受特定范围的字符串。我不知道如何以一种好的方式实现这一点。我现在有一个指定方法的接口。我还有一个实现接口的抽象类,它正在验证其构造函数中的字符串值。我很好奇我目前的设置是否良好,或者是否有更好的方法来做。下面是一个代码示例 public interface IStaticsRepository { int GetApiStatistics(string

我想从某种存储器中获取统计信息。因为我希望能够切换存储,所以我希望使用一个接口和程序来切换存储

不过,我需要对实现提出一些要求,比如只接受特定范围的字符串。我不知道如何以一种好的方式实现这一点。我现在有一个指定方法的接口。我还有一个实现接口的抽象类,它正在验证其构造函数中的字符串值。我很好奇我目前的设置是否良好,或者是否有更好的方法来做。下面是一个代码示例

public interface IStaticsRepository
{
    int GetApiStatistics(string apiId);
}

public abstract class StatisticsReposity : IStatisticsRepository
{
    public readonly ICollection<string> ValidTimeUnits = new[] { "hour", "day" };

    public StatisticsRepository(string timeUnit)
    {
        if (string.IsNullOrWhiteSpace(timeUnit))
        {
            throw new ArgumentNullException("timeUnit");
        }

        if (!ValidTimeUnits.Contains(timeUnit))
        {
            throw new ArgumentException("Now a valid time unit.", "timeUnit");
        }

        public abstract int GetApiStatistics(string apiId);
    }

    public class MongoDbStatisticsRepository : StatisticsRepository
    {
        public MongoDbStatisticsRepository(string timeUnit)
            : base(timeUnit)
        { }

        public override int GetApiStatistics(string apiId)
        { }
    }
公共接口IStaticsRepository
{
int getapistics(字符串apid);
}
公共抽象类统计报告:IStatisticsRepository
{
public readonly ICollection ValidTimeUnits=new[]{“hour”,“day”};
公共统计存储库(字符串时间单位)
{
if(string.IsNullOrWhiteSpace(时间单位))
{
抛出新的ArgumentNullException(“时间单位”);
}
如果(!ValidTimeUnits.Contains(timeUnit))
{
抛出新的ArgumentException(“现在是有效的时间单位。”,“时间单位”);
}
公共摘要int getapistics(字符串apid);
}
公共类MongoDbStatisticsRepository:统计存储库
{
公共MongoDBStatisticsRespository(字符串时间单位)
:基准(时间单位)
{ }
公共覆盖int GetApiStatistics(字符串APID)
{ }
}

使用抽象类是正常的做法,不能将输入要求放在接口本身上

唯一的另一种排序选项是编写单元测试,这些测试传递无效的日期,并检查以确保在预期抛出时抛出
ArgumentException


编辑:在看到其他注释和答案后,我没有意识到您基本上是在尝试重新创建一个
枚举
。阅读其他答案,这可能是您在现实中想要做的,并且比执行
!Contains>要快得多(

如果需要强类型,我建议使用枚举类型而不是字符串:


静态类型是您的朋友。如果出于任何原因需要字符串支持的类型,而不是使用int支持的枚举,我使用了如下模式:

public class TimeUnit
{
  private readonly string _unit;

  private TimeUnit(string unit)
  {
    _unit = unit;
  }

  public static readonly TimeUnit Hour = new TimeUnit("hour");
  public static readonly TimeUnit Day = new TimeUnit("day");
  public string ToString()
  {
    return _unit;
  }
}

这样,您仍然可以访问支持字符串,假设代码的其余部分依赖于此,但您也强制客户端传入
TimeUnit.Hour
TimeUnit.Day

如果您只接受
TimeUnit
的几个有效字符串,那么为什么不将其设置为
enum
?是的。当然可以答案是这样的。我最初使用enum,但后来有了一个好主意,允许实现者支持比“最小值”更多的内容有效的时间单位范围。但如果是这样的话,我们就不能强制验证。愚蠢的我。我仍然不知道为什么你不应该在这里使用枚举。你不想避免在多个位置使用魔法字符串吗?如果不是在一个地方,那么很难记住哪些是允许的时间单位。我不是有意建议枚举是不合适的,而且它们的重量肯定比这个轻。我发现,当我想要一个字符串随时可用于序列化目的,或者当我想要包含其他功能时,这是一个有用的模式。在不知道OPs场景的细节,并且看到他已经在使用字符串的情况下,我想我会抛出在某些情况下,枚举可能会更好,这一点很有道理。