一、场景假设

假设有一串字符串如下所示,字符串中的数字之间已用英文状态下的逗号隔开。要求用此字符串中的数字快速生成int类型的数组,且尽可能使用最少的代码量。

string str = "1,2,3,4,5,6,7,8,9";

二、解决方案

我相信大多数同学在拿到这题的时候,一般都会给出以下的解决方案:

public int[] String2IntArray(string str)
{
var strArr = str.Split(',');
int[] numArr = new int[strArr.Length];
for (int i = 0; i < strArr.Length; i++)
{
numArr[i] = Convert.ToInt32(strArr[i]);
}
return numArr;
}

上述代码确实能解决上述场景中的问题。

三、问题延伸

可是这时要求变了,改为生成char类型的数组。

这时一部分同学会说,既然让生成char类型数组,那我改下数据类型不就可以了嘛,于是给出如下代码:

public char[] String2CharArray(string str)
{
var strArr = str.Split(',');
char[] cArr = new char[strArr.Length];
for (int i = 0; i < strArr.Length; i++)
{
cArr[i] = Convert.ToChar(strArr[i]);
}
return cArr;
}

另外一部分同学会说,每改一下输出的数据类型就要再写一个相应的方法,这样不通用不是很好。能不能用泛型解决此问题呢?想了一下,给出了以下代码:

public T[] String2Array<T>(string str)
{
var tc = TypeDescriptor.GetConverter(typeof(T));
var strArr = str.Split(',');
T[] tArr = new T[strArr.Length];
for (int i = 0; i < strArr.Length; i++)
{
tArr[i] = (T)tc.ConvertTo(strArr[i], typeof(T));
}
return tArr;
}

上面泛型代码解决方案可圈可点,可通用性感觉还是较差,代码量还是有点多。

如果这时要求数组对象实例直接进行转换呢?这时有什么好的方案去解决问题呢?

四、数组类的静态转换方法

数组(Array)类直接提供了一个静态方法ConvertAll,该方法能将一种类型的数组转换为另一种类型的数组。该方法能有效的解决上述痛点问题。

1、首先我们来看一下这个方法的定义:

public static TOutput[] ConvertAll<TInput, TOutput>(TInput[] array, Converter<TInput, TOutput> converter)

  • 该方法没有重载方法,是类的静态方法,无需创建实例去调用。
  • TInput:源数组元素的类型。
  • TOutput:目标数组元素的类型。

上述问题用ConvertAll方法该如何编码呢?下面给出代码示例:

var arr = str.Split(',');
var numArr = Array.ConvertAll<string, int>(arr, z => int.Parse(z));

或者

var arr = str.Split(',');
var numArr = Array.ConvertAll<string, int>(arr, delegate (string s) { return int.Parse(s); });

ConvertAll方法仅有两行代码,与前述的解决方法相比,结果一目了然、不言而喻。

五、刨根问底

那ConvertAll是如何实现数组数据类型转换的呢?我们反编译一下该方法,得到如下代码:

public static TOutput[] ConvertAll<TInput, TOutput>(TInput[] array, Converter<TInput, TOutput> converter)
{
if (array == null)
{
throw new ArgumentNullException("array");
} if (converter == null)
{
throw new ArgumentNullException("converter");
} TOutput[] array2 = new TOutput[array.Length];
for (int i = 0; i < array.Length; i++)
{
array2[i] = converter(array[i]);
} return array2;
}

我们再看一下Converter是如何定义的:

public delegate TOutput Converter<in TInput, out TOutput>(TInput input);

知其然知其所以然,以后再遇到数组转换的问题我们就不用在怕了。

这时,有的同学可能会说:“在不知道Converter方法和其实现的提前下,我也是可能写出与Converter方法相同的实现代码的”。那不得不说你真的很棒,既然系统底层提供了该方法供我们使用,我们再编码一遍(提前是不知道Converter方法存在和其实现代码)岂不是有点多余?直接使用何乐而不为呢?

本篇文章我们经历了:提出问题->解决问题->延伸问题->刨根问底

这样的思考方式有助于我们快速提升编码能力,也希望这样的思考方式能给你们解决问题带来些许灵感。

---------------the end---------------

----------本篇文章到此结束----------

C# 一维数组如何快速实现数组元素的数据类型的转换?的更多相关文章

  1. javascript中快速求数组的全部元素的相加之和

    js中快速求数组的全部元素的相加之和: var arr = [1,2,3,4,5];var sum = eval(arr.join('+')); console.log(sum); 运行结果: 15

  2. JS判断数组中是否有重复元素的方法

    判断数组中是否有重复元素,最容易想到的方法是使用2重循环,逐个遍历,比较,但是这个是最慢,最笨的方法,百度得出了更好的方法. var ary = new Array("111",& ...

  3. C# 数组、一维数组、二维数组、多维数组、锯齿数组

    C#  数组.一维数组.二维数组.多维数组.锯齿数组 一.数组: 如果需要使用同一类型的对象,就可以使用数组,数组是一种数据结构,它可以包含同一类型的多个元素.它的长度是固定的,如长度未知的情况下,请 ...

  4. java基础5 (一维)数组和二维数组

    本文知识点(目录): 一维数组(一维数组的概念.优点.格式.定义.初始化.遍历.常见异常.内存分析以及常见操作(找最大值.选择排序.冒泡排序等等))    二维数组(二维数组的遍历.排序.查找.定义. ...

  5. C#数组--(一维数组,二维数组的声明,使用及遍历)

    数组:是具有相同数据类型的一组数据的集合.数组的每一个的变量称为数组的元素,数组能够容纳元素的数称为数组的长度. 一维数组:以线性方式存储固定数目的数组元素,它只需要1个索引值即可标识任意1个数组元素 ...

  6. Python输入数组(一维数组、二维数组)

    一维数组: arr = input("") //输入一个一维数组,每个数之间使空格隔开 num = [int(n) for n in arr.split()] //将输入每个数以空 ...

  7. 从数组中取出N个元素的所有组合——递归实现

    https://www.cnblogs.com/null00/archive/2012/04/27/2473788.html 今天在做POJ 1753时,需要枚举一个数组中所有组合.之前也遇到过类似的 ...

  8. 第3章 Java数组(上): 一维数组和二维数组

    3.数组及排序算法(2天) 3.1 数组的概述 2课时 3.2 一维数组的使用 3课时 3.3 多维数组的使用 3课时 3.4 数组中涉及到的常见算法 3课时 3.5 Arrays工具类的使用 3课时 ...

  9. 二维数组,锯齿数组和集合 C# 一维数组、二维数组(矩形数组)、交错数组(锯齿数组)的使用 C# 数组、多维数组(矩形数组)、锯齿数组(交叉数组)

    二维数组,锯齿数组和集合 一.二维数组 二维数组:一维数组----豆角二维数组----表格 定义:1.一维数组:数据类型[] 数组变量名 = new 数据类型[数组长度];数据类型[] 数组变量名 = ...

随机推荐

  1. Lock 深入理解acquire和release原理源码及lock独有特性acquireInterruptibly和tryAcquireNanos

    https://blog.csdn.net/sophia__yu/article/details/84313234 Lock是一个接口,通常会用ReentrantLock(可重入锁)来实现这个接口. ...

  2. 如何通过sql语句完成分页?

    oracle select rownum,bookId from [rownum是伪列名,bookId是列名] (select rownum row_id,bookId from xiaoWJ_boo ...

  3. mybatis中jdbcType和javaType

    1.MyBatis 通过包含的jdbcType类型 BIT.FLOAT.CHAR .TIMESTAMP . OTHER .UNDEFINEDTINYINT .REAL .VARCHAR .BINARY ...

  4. zookeeper 负载均衡和 nginx 负载均衡区别?

    zk 的负载均衡是可以调控,nginx 只是能调权重,其他需要可控的都需要自己写插件:但是 nginx 的吞吐量比 zk 大很多,应该说按业务选择用哪种方式.

  5. 解释 Spring 框架中 bean 的生命周期?

    Spring 容器 从 XML 文件中读取 bean 的定义,并实例化 bean. Spring 根据 bean 的定义填充所有的属性. 如果 bean 实现了 BeanNameAware 接口,Sp ...

  6. simulink模块使用方式

    逻辑模块 1.小于等于系列模块 Applies the selected relational operator to the inputs and outputs the result. The t ...

  7. 手把手教你从零写一个简单的 VUE

    本系列是一个教程,下面贴下目录~1.手把手教你从零写一个简单的 VUE2.手把手教你从零写一个简单的 VUE--模板篇 今天给大家带来的是实现一个简单的类似 VUE 一样的前端框架,VUE 框架现在应 ...

  8. Codepen 每日精选(2018-4-20)

    按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以打开原始页面. 图书打开的交互效果https://codepen.io/jcoulterde... 进度条交互效果http ...

  9. 关于sqlite数据库与sqlite studio

    今天使用了AS自带的sqlite实现了连接数据库,但是不能同步,比较麻烦,然后使用sqlite studio去设法实现同步,但是依旧无法创建成功,明天会继续调试.

  10. php运用validate+ajax检测用户名是否已存在

    前提:如果还不知道什么是validate,请前往这里 一.remote rules: username:{ required:true, minlength:8, maxlength:8, remot ...