【问题标题】:Using Generic T to Determine Compiler-Chosen Overload使用 Generic T 确定编译器选择的重载
【发布时间】:2014-11-27 07:22:07
【问题描述】:

我有以下代码。计划是让GetSetting() 调用适当版本的FromString(),具体取决于T 的类型。

public static T GetSetting<T>(PersistedSetting setting, T defaultValue = default(T))
{
    return FromString(RegistrySettings.GetSetting(setting.ToString()) as string, defaultValue);
}

private static string FromString(string value, string defaultValue)
{
    return value ?? String.Empty;
}

private static int FromString(string value, int defaultValue)
{
    int i;
    return int.TryParse(value, out i) ? i : defaultValue;
}

private static decimal FromString(string value, decimal defaultValue)
{
    decimal d;
    return decimal.TryParse(value, out d) ? d : defaultValue;
}

private static bool FromString(string value, bool defaultValue)
{
    bool b;
    return bool.TryParse(value, out b) ? b : defaultValue;
}

但是,在调用FromString() 的行上,我得到了编译错误:

'ArticleManager.PersistedSettings.FromString(string, string)' 的最佳重载方法匹配有一些无效参数

编译器假定FromString(string, string)。有没有办法让它为T 使用适当的重载?

编辑:

我不确定,但我对正在发生的事情的最佳猜测是重载是在编译时确定的,而 GetSetting() 直到运行时才知道类型。但是,如果这是问题所在,人们将如何解决这个特定问题?

【问题讨论】:

  • 编译器如何知道您不会使用 DateTime、long 或 Foo 调用 GetSetting?
  • @AnthonyPegram:嗯,这是一个有效的问题,但就目前而言,它似乎是一个单独的问题。现在,它假设我总是用一个字符串来调用它。不确定我是否理解为什么会发生这种情况,或者做我想做的事情的最佳方式。
  • 并不总是假设你用一个字符串来调用它,它只是从几个中选择一个作为有效的错误消息。事实是您的参数是 (string, T),并且您的重载都没有该签名,编译器只能拉出一个重载以包含在消息中。
  • 如果您没有 (string, string) 重载,编译器将简单地选择另一个重载以包含在错误消息中,因为它再次找不到任何适用的内容。
  • @AnthonyPegram:好的,我可以看到。谢谢。

标签: c# .net generics overloading


【解决方案1】:

重载选择确实发生在编译时。这就是问题所在。

您可以在运行时使用dynamic

return FromString(RegistrySettings.GetSetting(setting.ToString()) as string, (dynamic)defaultValue);

在 MSDN 上阅读更多信息:Using Type dynamic (C# Programming Guide)

或者您可以使您的方法成为非泛型方法,并为GetSetting 设置一组重载,例如

public static int GetSetting(PersistedSetting setting, int defaultValue = default(int))
{
    return FromString(RegistrySettings.GetSetting(setting.ToString()) as string, defaultValue);
}

【讨论】:

  • 这样使用dynamic有什么效果?它如何解决在编译时发生重载选择的事实?
  • 转换为dynamic 使得该特定调用的选择发生在运行时。它会让它变慢一点,因为必须在调用之前完成解析+如果在运行时没有找到合适的方法,你会得到一个异常。
  • @JonathanWood, dynamic 基本上是一种告诉编译器暂时忽略代码的某些方面并将这种类型的分析推迟到代码实际运行的方法.如果此时有任何违法行为,程序就会崩溃。
  • @MarcinJuraszek:是的,确实有效。但是,这是否意味着您所说的“在编译时确实发生了重载选择”有时才正确?
  • dynamic 是我所知道的唯一例外。
猜你喜欢
  • 2015-05-19
  • 2014-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多