ChatGPT解决这个技术问题 Extra ChatGPT

如何使方法的返回类型通用?

有没有办法让这个方法通用,所以我可以返回一个字符串、布尔值、整数或双精度值?现在,它正在返回一个字符串,但如果它能够找到“true”或“false”作为配置值,我想返回一个 bool 例如。

    public static string ConfigSetting(string settingName)
    {  
         return ConfigurationManager.AppSettings[settingName];
    }
有没有办法让您知道每个设置是什么类型?
我认为您真正想问的问题是“如何使我的应用程序配置成为强类型?”不过,自从我使用它来写一个正确的答案以来已经太久了。
是的,理想情况下我不想将类型传递给方法。我只会有我提到的4种类型。所以如果设置了“true”/“false”,我希望这个函数返回一个布尔值(不需要将它传递给方法),我可能可以将 int 和 double 组合成 double,其他一切都应该是一个字符串。已经回答的内容可以正常工作,但我每次都需要传递类型,这可能没问题。
您的评论听起来像是您在要求一种方法,该方法将根据为设置名称检索到的实际数据在运行时返回强类型的 bool(或字符串、或 int 或其他类型)钥匙。 C# 不会为你这样做;您无法在编译时知道该值的类型。换句话说,这是动态类型,而不是静态类型。如果您使用 dynamic 关键字,C# 可以为您做到这一点。这需要性能成本,但对于读取配置文件,性能成本几乎可以肯定是微不足道的。

J
Jon Skeet

您需要使其成为通用方法,如下所示:

public static T ConfigSetting<T>(string settingName)
{  
    return /* code to convert the setting to T... */
}

但是调用者必须指定他们期望的类型。然后您可以使用 Convert.ChangeType,假设支持所有相关类型:

public static T ConfigSetting<T>(string settingName)
{  
    object value = ConfigurationManager.AppSettings[settingName];
    return (T) Convert.ChangeType(value, typeof(T));
}

我不完全相信这一切都是个好主意,请注意...


/* 将设置转换为 T 的代码... */ 下面是整部小说 :)
这是否不需要您知道您希望获得的设置类型,这可能是不可能的。
@thecoshman:会的,但是如果您不这样做,那么您将如何处理返回的值?
虽然这个答案当然是正确的,并且您注意到满足了 OP 的要求,但可能值得一提的是,单独方法(ConfigSettingStringConfigSettingBool 等)的旧方法具有方法主体更短的优点,更清晰,更专注。
如果不建议这样做,那么通用返回类型的目的是什么?
B
BrokenGlass

您可以使用 Convert.ChangeType()

public static T ConfigSetting<T>(string settingName)
{
    return (T)Convert.ChangeType(ConfigurationManager.AppSettings[settingName], typeof(T));
}

R
RollerCosta

有很多方法可以做到这一点(按优先级列出,特定于 OP 的问题)

选项 1:直接方法 - 为您期望的每种类型创建多个函数,而不是使用一个通用函数。 public static bool ConfigSettingInt(string settingName) { return Convert.ToBoolean(ConfigurationManager.AppSettings[settingName]);选项 2:当您不想使用花哨的转换方法时 - 将值转换为对象,然后转换为泛型类型。公共静态 T ConfigSetting(string settingName) { return (T)(object)ConfigurationManager.AppSettings[settingName];注意 - 如果演员表无效(您的情况),这将引发错误。如果您不确定类型转换,我不建议您这样做,而是选择选项 3。 选项 3:具有类型安全的泛型 - 创建一个泛型函数来处理类型转换。 public static T ConvertValue(U value) where U : IConvertible { return (T)Convert.ChangeType(value, typeof(T));注意 - T 是预期的类型,请注意此处的 where 约束(U 的类型必须是 IConvertible 以使我们免于错误)


为什么在 U 中将第三个选项设为通用?这样做没有任何意义,而且它使方法更难调用。只需接受 IConvertible。我认为这个问题不值得包含第二个选项,因为它没有回答所提出的问题。您可能还应该重命名第一个选项中的方法...
V
Vinay Chanumolu

您必须将方法的返回值的类型转换为在调用期间传递给方法的通用类型。

    public static T values<T>()
    {
        Random random = new Random();
        int number = random.Next(1, 4);
        return (T)Convert.ChangeType(number, typeof(T));
    }

您需要为通过该方法返回的值传递一个可强制类型转换的类型。

如果您想要返回一个不可类型转换的值到您传递的泛型类型,您可能必须更改代码或确保您传递的类型可转换为方法的返回值。因此,不推荐这种方法。


准确 - 对我来说,最后一行 return (T)Convert.ChangeType(number, typeof(T)); 正是我所缺少的 - 欢呼
P
Prabhakar

创建一个函数并将 put 参数作为泛型类型传递。

 public static T some_function<T>(T out_put_object /*declare as Output object*/)
    {
        return out_put_object;
    }

对于一些用例来说,这实际上非常聪明。就像从数据库中提取数据一样。你知道你会得到一个 T 类型的数据列表。加载方法只是不知道你现在想要什么类型的 T。因此,只需将一个新的 List 传递给它,该方法就可以完成它的工作并在返回之前填充列表。好的!
S
Sid

请尝试以下代码:

public T? GetParsedOrDefaultValue<T>(string valueToParse) where T : struct, IComparable
{
 if(string.EmptyOrNull(valueToParse))return null;
  try
  {
     // return parsed value
     return (T) Convert.ChangeType(valueToParse, typeof(T));
  }
  catch(Exception)
  {
   //default as null value
   return null;
  }
 return null;
}

A
Adam Howard
 private static T[] prepareArray<T>(T[] arrayToCopy, T value)
    {
        Array.Copy(arrayToCopy, 1, arrayToCopy, 0, arrayToCopy.Length - 1);
        arrayToCopy[arrayToCopy.Length - 1] = value;
        return (T[])arrayToCopy;
    }

我在整个代码中都在执行此操作,并且想要一种将其放入方法中的方法。我想在这里分享这个,因为我不必使用 Convert.ChangeType 作为我的返回值。这可能不是最佳实践,但对我有用。此方法接受一个泛型类型的数组和一个要添加到数组末尾的值。然后复制该数组,并删除第一个值,并将该方法中的值添加到数组的末尾。最后一件事是我返回通用数组。