如何将字符串数组转换为泛型数组类型,同时允许非数组和数组作为 class 的泛型类型参数?
How to convert a string array to a generic array type while allowing both non array and array as generic type parameter for the class?
我有一个 Option<T>
,它适用于从字符串转换而来的任何类型,现在我正在尝试扩展它以涵盖 Option<T[]>
(即 Option<int[]>)
)。害怕我可能会遇到这个问题,因为我手下有太多的 C++ 模板。我无法解决看似不足的 C# 泛型问题。我可以检测到 T 何时是数组,但我无法使用 typeof(T).GetElementType()
.
我想我可能处于那些 XY 问题谷中的一个,我只是从错误的方向来到这里,看不到上升的路径。任何想法如何获得畅通无阻?我已经尝试了所有我能想到的方法,并在过去的几天里试图弄清楚如何解除封锁。
我要补充一点,我可以安排在转换之前将逗号分隔的字符串解析为字符串数组。下面的代码是我尝试过的一些代码的简化摘录。
using System;
using System.Collections.Generic;
namespace WhosebugCS
{
internal static class ConversionExtensionMethods
{
internal static T ChangeType<T>(this object obj)
{
try
{
return (T)Convert.ChangeType(obj, typeof(T));
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
internal static T ChangeType<T>(this object[] objects)
{
try
{
if (!typeof(T).IsArray) throw new Exception("T is not an array type.");
var converted = new object[objects.Length];
foreach (var item in objects)
{
// AFAIK, converstion requires compile time knowledge of T.GetElementType(),
// but this won't compile.
converted.Add(item.ChangeType<typeof(T).GetElementType())>
}
return (T)converted; // And this won't compile either.
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
}
internal class Option<T>
{
public T Value;
public Option() {}
// This works fine for non-arrays
public bool SetValue(string valueString)
{
try
{
Value = valueString.ChangeType<T>();
}
catch (Exception e)
{
Console.WriteLine(e);
return false;
}
return true;
}
// I think I am in an XY problem valley here.
public bool SetValue(string[] valueStrings)
{
try
{
if (!typeof(T).IsArray)
{
throw new Exception("T is not an array type.");
}
// The crux of my problem is I can't seem to write pure generic code in C#
var convertedElements = new List<!!!Cannot use typeof(T).GetElementType() here!!!>();
foreach (var item in valueStrings)
{
// The crux of my problem is I can't seem to write pure generic code in C#
convertedElements.Add(!!!Cannot use typeof(T).GetElementType() here!!!);
}
}
catch (Exception e)
{
Console.WriteLine(e);
return false;
}
return true;
}
}
public class Program
{
static void Main(string[] args)
{
var opt = new Option<int>(); // Works fine.
var integerList = new Option<int[]>();
integerList.SetValue("this,that,whatever"); // This fails at run-time.
foreach (var item in integerList.Value)
{
Console.WriteLine(item);
}
Console.ReadKey();
}
}
}
解析器(未显示)可以检测形式为
的参数
Opt:1,2,3
或
Opt:"short sentence",word,"string with quotes\" in it"
,等等
我宁愿不让解析器尝试弄清楚 Opt Option 的数组元素是什么类型。 Option<T>.SetValue(string[] strings)
函数应该能够处理这个问题。
我什至还没有尝试过 test/implement `Options ,尽管我怀疑那样会容易得多。
您可以试试这个以允许 non-array 和数组泛型类型参数:
using System;
using System.Linq;
SetValue(字符串值字符串)
public bool SetValue(string valueString)
{
try
{
if ( typeof(T).IsArray ) throw new Exception("T is an array type.");
Value = (T)Convert.ChangeType(valueString, typeof(T));
}
catch ( Exception e )
{
Console.WriteLine(e);
return false;
}
return true;
}
SetValue(字符串[] valueStrings)
public bool SetValue(string[] valueStrings)
{
try
{
if ( !typeof(T).IsArray ) throw new Exception("T is not an array type.");
var thetype = typeof(T).GetElementType();
var list = valueStrings.Select(s => Convert.ChangeType(s, thetype)).ToList();
var array = Array.CreateInstance(thetype, list.Count);
for (int index = 0; index < list.Count; index++ )
array.SetValue(list[index], index);
Value = (T)Convert.ChangeType(array, typeof(T));
}
catch ( Exception e )
{
Console.WriteLine(e);
return false;
}
return true;
}
测试
static void Main(string[] args)
{
// Non array
var opt = new Option<int>();
opt.SetValue("10");
Console.WriteLine(opt.Value);
Console.WriteLine();
// Array
var integerList = new Option<int[]>();
integerList.SetValue(new[] { "1", "2", "3" });
foreach ( var item in integerList.Value )
Console.WriteLine(item);
// End
Console.ReadKey();
}
输出
10
1
2
3
我有一个 Option<T>
,它适用于从字符串转换而来的任何类型,现在我正在尝试扩展它以涵盖 Option<T[]>
(即 Option<int[]>)
)。害怕我可能会遇到这个问题,因为我手下有太多的 C++ 模板。我无法解决看似不足的 C# 泛型问题。我可以检测到 T 何时是数组,但我无法使用 typeof(T).GetElementType()
.
我想我可能处于那些 XY 问题谷中的一个,我只是从错误的方向来到这里,看不到上升的路径。任何想法如何获得畅通无阻?我已经尝试了所有我能想到的方法,并在过去的几天里试图弄清楚如何解除封锁。 我要补充一点,我可以安排在转换之前将逗号分隔的字符串解析为字符串数组。下面的代码是我尝试过的一些代码的简化摘录。
using System;
using System.Collections.Generic;
namespace WhosebugCS
{
internal static class ConversionExtensionMethods
{
internal static T ChangeType<T>(this object obj)
{
try
{
return (T)Convert.ChangeType(obj, typeof(T));
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
internal static T ChangeType<T>(this object[] objects)
{
try
{
if (!typeof(T).IsArray) throw new Exception("T is not an array type.");
var converted = new object[objects.Length];
foreach (var item in objects)
{
// AFAIK, converstion requires compile time knowledge of T.GetElementType(),
// but this won't compile.
converted.Add(item.ChangeType<typeof(T).GetElementType())>
}
return (T)converted; // And this won't compile either.
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
}
internal class Option<T>
{
public T Value;
public Option() {}
// This works fine for non-arrays
public bool SetValue(string valueString)
{
try
{
Value = valueString.ChangeType<T>();
}
catch (Exception e)
{
Console.WriteLine(e);
return false;
}
return true;
}
// I think I am in an XY problem valley here.
public bool SetValue(string[] valueStrings)
{
try
{
if (!typeof(T).IsArray)
{
throw new Exception("T is not an array type.");
}
// The crux of my problem is I can't seem to write pure generic code in C#
var convertedElements = new List<!!!Cannot use typeof(T).GetElementType() here!!!>();
foreach (var item in valueStrings)
{
// The crux of my problem is I can't seem to write pure generic code in C#
convertedElements.Add(!!!Cannot use typeof(T).GetElementType() here!!!);
}
}
catch (Exception e)
{
Console.WriteLine(e);
return false;
}
return true;
}
}
public class Program
{
static void Main(string[] args)
{
var opt = new Option<int>(); // Works fine.
var integerList = new Option<int[]>();
integerList.SetValue("this,that,whatever"); // This fails at run-time.
foreach (var item in integerList.Value)
{
Console.WriteLine(item);
}
Console.ReadKey();
}
}
}
解析器(未显示)可以检测形式为
的参数
Opt:1,2,3
或
Opt:"short sentence",word,"string with quotes\" in it"
,等等
我宁愿不让解析器尝试弄清楚 Opt Option 的数组元素是什么类型。 Option<T>.SetValue(string[] strings)
函数应该能够处理这个问题。
我什至还没有尝试过 test/implement `Options ,尽管我怀疑那样会容易得多。
您可以试试这个以允许 non-array 和数组泛型类型参数:
using System;
using System.Linq;
SetValue(字符串值字符串)
public bool SetValue(string valueString)
{
try
{
if ( typeof(T).IsArray ) throw new Exception("T is an array type.");
Value = (T)Convert.ChangeType(valueString, typeof(T));
}
catch ( Exception e )
{
Console.WriteLine(e);
return false;
}
return true;
}
SetValue(字符串[] valueStrings)
public bool SetValue(string[] valueStrings)
{
try
{
if ( !typeof(T).IsArray ) throw new Exception("T is not an array type.");
var thetype = typeof(T).GetElementType();
var list = valueStrings.Select(s => Convert.ChangeType(s, thetype)).ToList();
var array = Array.CreateInstance(thetype, list.Count);
for (int index = 0; index < list.Count; index++ )
array.SetValue(list[index], index);
Value = (T)Convert.ChangeType(array, typeof(T));
}
catch ( Exception e )
{
Console.WriteLine(e);
return false;
}
return true;
}
测试
static void Main(string[] args)
{
// Non array
var opt = new Option<int>();
opt.SetValue("10");
Console.WriteLine(opt.Value);
Console.WriteLine();
// Array
var integerList = new Option<int[]>();
integerList.SetValue(new[] { "1", "2", "3" });
foreach ( var item in integerList.Value )
Console.WriteLine(item);
// End
Console.ReadKey();
}
输出
10
1
2
3