C# 一维数组如何快速实现数组元素的数据类型的转换?
一、场景假设
假设有一串字符串如下所示,字符串中的数字之间已用英文状态下的逗号隔开。要求用此字符串中的数字快速生成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# 一维数组如何快速实现数组元素的数据类型的转换?的更多相关文章
- javascript中快速求数组的全部元素的相加之和
js中快速求数组的全部元素的相加之和: var arr = [1,2,3,4,5];var sum = eval(arr.join('+')); console.log(sum); 运行结果: 15
- JS判断数组中是否有重复元素的方法
判断数组中是否有重复元素,最容易想到的方法是使用2重循环,逐个遍历,比较,但是这个是最慢,最笨的方法,百度得出了更好的方法. var ary = new Array("111",& ...
- C# 数组、一维数组、二维数组、多维数组、锯齿数组
C# 数组.一维数组.二维数组.多维数组.锯齿数组 一.数组: 如果需要使用同一类型的对象,就可以使用数组,数组是一种数据结构,它可以包含同一类型的多个元素.它的长度是固定的,如长度未知的情况下,请 ...
- java基础5 (一维)数组和二维数组
本文知识点(目录): 一维数组(一维数组的概念.优点.格式.定义.初始化.遍历.常见异常.内存分析以及常见操作(找最大值.选择排序.冒泡排序等等)) 二维数组(二维数组的遍历.排序.查找.定义. ...
- C#数组--(一维数组,二维数组的声明,使用及遍历)
数组:是具有相同数据类型的一组数据的集合.数组的每一个的变量称为数组的元素,数组能够容纳元素的数称为数组的长度. 一维数组:以线性方式存储固定数目的数组元素,它只需要1个索引值即可标识任意1个数组元素 ...
- Python输入数组(一维数组、二维数组)
一维数组: arr = input("") //输入一个一维数组,每个数之间使空格隔开 num = [int(n) for n in arr.split()] //将输入每个数以空 ...
- 从数组中取出N个元素的所有组合——递归实现
https://www.cnblogs.com/null00/archive/2012/04/27/2473788.html 今天在做POJ 1753时,需要枚举一个数组中所有组合.之前也遇到过类似的 ...
- 第3章 Java数组(上): 一维数组和二维数组
3.数组及排序算法(2天) 3.1 数组的概述 2课时 3.2 一维数组的使用 3课时 3.3 多维数组的使用 3课时 3.4 数组中涉及到的常见算法 3课时 3.5 Arrays工具类的使用 3课时 ...
- 二维数组,锯齿数组和集合 C# 一维数组、二维数组(矩形数组)、交错数组(锯齿数组)的使用 C# 数组、多维数组(矩形数组)、锯齿数组(交叉数组)
二维数组,锯齿数组和集合 一.二维数组 二维数组:一维数组----豆角二维数组----表格 定义:1.一维数组:数据类型[] 数组变量名 = new 数据类型[数组长度];数据类型[] 数组变量名 = ...
随机推荐
- Lock 深入理解acquire和release原理源码及lock独有特性acquireInterruptibly和tryAcquireNanos
https://blog.csdn.net/sophia__yu/article/details/84313234 Lock是一个接口,通常会用ReentrantLock(可重入锁)来实现这个接口. ...
- 如何通过sql语句完成分页?
oracle select rownum,bookId from [rownum是伪列名,bookId是列名] (select rownum row_id,bookId from xiaoWJ_boo ...
- mybatis中jdbcType和javaType
1.MyBatis 通过包含的jdbcType类型 BIT.FLOAT.CHAR .TIMESTAMP . OTHER .UNDEFINEDTINYINT .REAL .VARCHAR .BINARY ...
- zookeeper 负载均衡和 nginx 负载均衡区别?
zk 的负载均衡是可以调控,nginx 只是能调权重,其他需要可控的都需要自己写插件:但是 nginx 的吞吐量比 zk 大很多,应该说按业务选择用哪种方式.
- 解释 Spring 框架中 bean 的生命周期?
Spring 容器 从 XML 文件中读取 bean 的定义,并实例化 bean. Spring 根据 bean 的定义填充所有的属性. 如果 bean 实现了 BeanNameAware 接口,Sp ...
- simulink模块使用方式
逻辑模块 1.小于等于系列模块 Applies the selected relational operator to the inputs and outputs the result. The t ...
- 手把手教你从零写一个简单的 VUE
本系列是一个教程,下面贴下目录~1.手把手教你从零写一个简单的 VUE2.手把手教你从零写一个简单的 VUE--模板篇 今天给大家带来的是实现一个简单的类似 VUE 一样的前端框架,VUE 框架现在应 ...
- Codepen 每日精选(2018-4-20)
按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以打开原始页面. 图书打开的交互效果https://codepen.io/jcoulterde... 进度条交互效果http ...
- 关于sqlite数据库与sqlite studio
今天使用了AS自带的sqlite实现了连接数据库,但是不能同步,比较麻烦,然后使用sqlite studio去设法实现同步,但是依旧无法创建成功,明天会继续调试.
- php运用validate+ajax检测用户名是否已存在
前提:如果还不知道什么是validate,请前往这里 一.remote rules: username:{ required:true, minlength:8, maxlength:8, remot ...