C#中下限非零的数组解析
谈到数组时,当被问及数组是从什么数开始时,估计大部分程序员都会直接说出数组当然是从0开始的。这个回答当然没有错,现在我们就来了解一下C#中的下限非0的数组。
首先看一下数组的相关介绍:
1.数组:是允许将多个数据项当作一个集合来处理的机制。
2.数组的分类:在CLR中,数组可分为一维数组,多维数组,交错数组。
3.数组的类型:由于所有的数组都是继承自System.Array这个抽象类型,而这个类型又是继承自System.Object,这就说明数组是引用类型。
在创建数组时,除了有数组元素,数组对象占据的内存块还包含一个类型对象指针,一个同步索引块和一个额外的成员。上面对数组的分类中提到“交错数组”,由于CLR支持交错数组,所以在C#中可以实现交错数组,交错数组即由数组构成的数组,在访问交错数组的元素意味着必须进行两次或多次数组访问。
在对数组进行相关操作的过程中,数组作为实参传给一个方法时,实际传递的是对该数组的引用,因此被调用的方法能够修改数组中的元素。(如果不想被修改,必须生成数组的一个拷贝,并将这个拷贝传给方法。)
下面介绍一种将数组转化为DataTable的方法:
/// <summary> /// 整数型二维数组转换成DataTable /// </summary> /// <param name="intDyadicArray"></param> /// <param name="messageOut"></param> /// <param name="dataTableColumnsName"></param> /// <returns></returns> public DataTable DyadicArrayToDataTable(int[,] intDyadicArray, out string messageOut, params object[] dataTableColumnsName) { var returnDataTable = new DataTable(); //验证列与所传入的字符是否相符 if (dataTableColumnsName.Length != intDyadicArray.GetLength(1)) { messageOut = "DataTable列数与二维数组列数不符,请调整列数"; return returnDataTable; } //添加列 for (var dataTableColumnsCount = 0; dataTableColumnsCount < dataTableColumnsName.Length; dataTableColumnsCount++) { returnDataTable.Columns.Add(dataTableColumnsName[dataTableColumnsCount].ToString()); } //添加行 for (var dyadicArrayRow = 0; dyadicArrayRow < intDyadicArray.GetLength(0); dyadicArrayRow++) { var addDataRow = returnDataTable.NewRow(); for (var dyadicArrayColumns = 0; dyadicArrayColumns < intDyadicArray.GetLength(1); dyadicArrayColumns++) { addDataRow[dataTableColumnsName[dyadicArrayColumns].ToString()] = intDyadicArray[dyadicArrayRow, dyadicArrayColumns]; } returnDataTable.Rows.Add(addDataRow); } //返回提示与DataTable messageOut = "DataTable成功转换"; return returnDataTable; }
以上是将整数数组转化为DataTable的操作方法,至于其他类型,如字节,浮点型等类型的转化,修改相关参数即可,也可将参数类型进行对应的修改,这里就不做详细介绍了。
接下来我们具体来了解一下“下限非零数组”的相关知识:
下限非零数组由于在性能上没有做更好的优化,因此在一般的使用中会较少,如果不计较性能损失或者需要跨语言移植,可以考虑使用非零数组。“下限非零数组”的概念就不做介绍,正如其名称所见。
C#中使用Array的CreateInstance()方法进行创建,此方法有若干个重载,允许指定数组元素类型,数组维数,每一维的下限和每一维的元素数目。
在调用CreateInstance()时,为数组分配内存,将参数信息保存到数组的内存的开销部分,然后返回对数组的一个引用。
接下来看一下此方法的底层实现代码:
[System.Security.SecuritySafeCritical] // auto-generated public unsafe static Array CreateInstance(Type elementType, int length) { if ((object)elementType == null) throw new ArgumentNullException("elementType"); if (length < 0) throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); Contract.Ensures(Contract.Result<Array>() != null); Contract.Ensures(Contract.Result<Array>().Length == length); Contract.Ensures(Contract.Result<Array>().Rank == 1); Contract.EndContractBlock(); RuntimeType t = elementType.UnderlyingSystemType as RuntimeType; if (t == null) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"elementType"); return InternalCreate((void*)t.TypeHandle.Value,1,&length,null); }
看到以上的代码,应该对非零基数组的创建有一个大致了解,接下来具体看一下Ensures()方法的底层代码:
public static void Ensures(bool condition) { AssertMustUseRewriter(ContractFailureKind.Postcondition, "Ensures"); }
[SecuritySafeCritical] static partial void AssertMustUseRewriter(ContractFailureKind kind, String contractKind) { if (_assertingMustUseRewriter) System.Diagnostics.Assert.Fail("Asserting that we must use the rewriter went reentrant.", "Didn't rewrite this mscorlib?"); _assertingMustUseRewriter = true; Assembly thisAssembly = typeof(Contract).Assembly; StackTrace stack = new StackTrace(); Assembly probablyNotRewritten = null; for (int i = 0; i < stack.FrameCount; i++) { Assembly caller = stack.GetFrame(i).GetMethod().DeclaringType.Assembly; if (caller != thisAssembly) { probablyNotRewritten = caller; break; } } if (probablyNotRewritten == null) probablyNotRewritten = thisAssembly; String simpleName = probablyNotRewritten.GetName().Name; System.Runtime.CompilerServices.ContractHelper.TriggerFailure(kind, Environment.GetResourceString("MustUseCCRewrite", contractKind, simpleName), null, null, null); _assertingMustUseRewriter = false; }
有关非零基数组的创建方法就不做深入的介绍,如果需要使用,可以根据提供的方法重载选择对应的版本实现。

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

C语言中通过转义序列处理特殊字符,如:\n表示换行符。\t表示制表符。使用转义序列或字符常量表示特殊字符,如char c = '\n'。注意,反斜杠需要转义两次。不同平台和编译器可能有不同的转义序列,请查阅文档。

在 C 语言中,char 类型在字符串中用于:1. 存储单个字符;2. 使用数组表示字符串并以 null 终止符结束;3. 通过字符串操作函数进行操作;4. 从键盘读取或输出字符串。

在 C 语言中,char 和 wchar_t 的主要区别在于字符编码:char 使用 ASCII 或扩展 ASCII,wchar_t 使用 Unicode;char 占用 1-2 个字节,wchar_t 占用 2-4 个字节;char 适用于英语文本,wchar_t 适用于多语言文本;char 广泛支持,wchar_t 依赖于编译器和操作系统是否支持 Unicode;char 的字符范围受限,wchar_t 的字符范围更大,并使用专门的函数进行算术运算。

C 语言中符号的使用方法涵盖算术、赋值、条件、逻辑、位运算符等。算术运算符用于基本数学运算,赋值运算符用于赋值和加减乘除赋值,条件运算符用于根据条件执行不同操作,逻辑运算符用于逻辑操作,位运算符用于位级操作,特殊常量用于表示空指针、文件结束标记和非数字值。

多线程和异步的区别在于,多线程同时执行多个线程,而异步在不阻塞当前线程的情况下执行操作。多线程用于计算密集型任务,而异步用于用户交互操作。多线程的优势是提高计算性能,异步的优势是不阻塞 UI 线程。选择多线程还是异步取决于任务性质:计算密集型任务使用多线程,与外部资源交互且需要保持 UI 响应的任务使用异步。

在 C 语言中,char 类型转换可以通过:强制类型转换:使用强制类型转换符将一种类型的数据直接转换为另一种类型。自动类型转换:当一种类型的数据可以容纳另一种类型的值时,编译器自动进行转换。

char 数组在 C 语言中存储字符序列,声明为 char array_name[size]。访问元素通过下标运算符,元素以空终止符 '\0' 结尾,用于表示字符串终点。C 语言提供多种字符串操作函数,如 strlen()、strcpy()、strcat() 和 strcmp()。

C语言中没有内置求和函数,需自行编写。可通过遍历数组并累加元素实现求和:循环版本:使用for循环和数组长度计算求和。指针版本:使用指针指向数组元素,通过自增指针遍历高效求和。动态分配数组版本:动态分配数组并自行管理内存,确保释放已分配内存以防止内存泄漏。
