gpt4 book ai didi

c# - 在 C# 中将字符串转换为泛型类型(基本或数组)

转载 作者:行者123 更新时间:2023-11-30 13:47:59 28 4
gpt4 key购买 nike

我想将字符串转换为给定的泛型类型 T。它可以是基本类型或字符串(例如 intstring),也可以是基本类型或字符串的数组(例如 int[]string[])。我有以下功能:

T Str2Val<T>(string str)
{
return (T)Convert.ChangeType(str, typeof(T));
}

它适用于基本类型。但是当 T 是一个数组 E[]str 是一个逗号分隔的值列表时它失败了。

我可以很容易地检查 T 是否是一个带有 typeof(T).IsArray 的数组。然后我有两个解决方案:使用标量在同一函数中解析数组,如下所示:

  if (!typeof(T).IsArray)
{
return (T)Convert.ChangeType(str, typeof(T));
}
else
{
// Handle an array
}

或实现两个重载函数:一个用于通用 T,第二个用于通用 E[]。但是,这两种解决方案都失败了。我不能在 else 子句中使用任何特定于数组的代码,因为它必须与标量兼容。当 T 实际上是一个数组时,C# 无法使用 E[] 选择适当的重载。

我该怎么办?

最佳答案

我会创建一些您注册的自定义解析器列表,然后稍后利用,因为您似乎无论如何都想使用自定义规则:

public static class StringParsers
{
private static Dictionary<Type, object> Parsers = new Dictionary<Type, object>();

public static void RegisterParser<T>(Func<string, T> parseFunction)
{
Parsers[typeof(T)] = parseFunction;
}

public static T Parse<T>(string input)
{
object untypedParser;
if (!Parsers.TryGetValue(typeof(T), out untypedParser))
throw new Exception("Could not find a parser for type " + typeof(T).FullName);

Func<string, T> parser = (Func<string, T>)untypedParser;

return parser(input);
}
}

在您的应用程序初始化期间,您将注册您打算稍后在您的应用程序中使用的类型(我猜这是已知的,因为您正在使用泛型):

StringParsers.RegisterParser<string[]>(input => input.Split(','));
StringParsers.RegisterParser<int[]>(input => input.Split(',').Select(i => Int32.Parse(i)).ToArray());
StringParsers.RegisterParser<int>(input => Int32.Parse(input));

最后,你可以简单地调用它:

string testArrayInput = "1,2,8";

int[] integers = StringParsers.Parse<int[]>(testArrayInput); // {1, 2, 8}

string[] strings = StringParsers.Parse<string[]>(testArrayInput); // {"1", "2", "8"}

int singleInt = StringParsers.Parse<int>("9999"); //9999

现在,这是一个非常简单的实现。您可能希望扩展它而不是使用类型 Func<string, T>它可能使用 IStringParser接口(interface),如有必要,您可以提供更深入的解析实现。此外,您可能希望使其成为线程安全的(除非您确定这不会成为问题,或者如果您确定启动时的注册任何使用之前)

编辑:如果你真的,真的,真的想要在一个函数中全部只是考虑你的逗号分隔数组,那么你可以使用这个:

public static T Str2Val<T>(string str)
{
if (!typeof(T).IsArray)
return (T)Convert.ChangeType(str, typeof(T));

Type elementType = typeof(T).GetElementType();

string[] entries = str.Split(',');
int numberOfEntries = entries.Length;

System.Array array = Array.CreateInstance(elementType, numberOfEntries);

for(int i = 0; i < numberOfEntries; i++)
array.SetValue(Convert.ChangeType(entries[i], elementType), i);

return (T)(object)array;
}

但这感觉很错误。一定有更好的方法来避免 Alexander 的回答中的双重通用输入,但就这样吧。

关于c# - 在 C# 中将字符串转换为泛型类型(基本或数组),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14257207/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com