【问题标题】:Why does C# not contain IParsable<T> or ITryParsable<T>?为什么 C# 不包含 IParsable<T> 或 ItryParsable<T>?
【发布时间】:2013-12-09 14:16:58
【问题描述】:

编辑:显然这是不可能的C# does not allow static methods in interfaces

显然,为您自己的解决方案实现以下接口相当简单

public interface IParsable<T>
{
    T Parse(string s);
}

public interface ITryParsable<T> : IParsable<T>
{
    bool TryParse(string s, out T output);
}

一直在编写解析未知类型用户输入数据的各种方法,我会发现让intdecimal 等实现这些接口的一个版本是必不可少的。

对我来说,将其包含在 System 命名空间中似乎是一件相当明显的事情。

显然情况并非如此。那么查看一个类是否“实现”这些接口的最佳方法是什么?

通过Duck Typing 检查该方法是否存在似乎是一个明智的选择,但反射的性能并不是非常好。

【问题讨论】:

  • “解决这个问题的最佳方法是什么?” - 如果“this”是基类库中缺少的接口,那么您别无选择手动编写界面。你能试着解释你的实际问题吗?我想您有某种类型的变量,并且您想尝试将其解析为任何其他类型并查看哪个有效?
  • 那些是静态方法(它们创建一个实例,那么你会在哪个实例上调用它们?)。接口只支持实例方法。
  • @CodesInChaos D'oh。好点。
  • “但反射的性能并不是非常好。” - 通过一些缓存,它非常快。我写了such a caching parser
  • @CodesInChaos 谢谢,看起来不错。 此刻感觉很愚蠢(现在是星期一)。

标签: c#


【解决方案1】:

由于 C# 不支持静态接口,因此您必须拥有对象的实例才能调用 parse 方法。你最终会得到这样的结果:

var a = new int().Parse<int>("123");
var b = 123.Parse("567");

或者使用TryParse 方法,事情变得更加奇怪:

int x;
if (x.TryParse("456", out x))
    // trippy... now imagine that x is a reference type...

【讨论】:

  • var p = default(int); p.Parse("567"); Console.WriteLine(p); 对我来说并没有不好,尽管我承认这很令人困惑,可能不值得努力。
  • @CodesInChaos 缺少构造函数括号。已编辑。
  • @hvd,如果这对你来说没问题,你总是可以编写相应的扩展方法,因为这在 C# 中是可能的
  • 即使有括号,代码也没有意义。在Object 的实例上调用通用Parse 方法。这将如何启用接口?
  • @IvayloSlavov 在我的示例中,我使用了p.Parse("567");,它将修改p。这可以通过int 上的实例方法实现,但不能通过int 上的扩展方法实现。
【解决方案2】:

使用 .NET 6 Preview Generic Math,这确实存在!

IParsableITryParsable 尚不存在,这些方法在 INumber 接口中

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-16
    • 1970-01-01
    • 2021-02-08
    • 2012-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多