共创福州网站建设,成都公司注册流程及需要的材料,吴忠市建设局官方网站,凡科网官网登录入口CCLI——4数组、泛型、集合与属性
C数组
在c中#xff0c;数组的大小必须在编译时确定#xff0c;并且将数组传递给函数时#xff0c;传递的只是数组起始地址#xff0c;所以要想办法连同数组大小一同传递给函数。
int arr[4] { 1,2,3,4 };
int arr1[] { 1,2,3,4 };
i…CCLI——4数组、泛型、集合与属性
C数组
在c中数组的大小必须在编译时确定并且将数组传递给函数时传递的只是数组起始地址所以要想办法连同数组大小一同传递给函数。
int arr[4] { 1,2,3,4 };
int arr1[] { 1,2,3,4 };
int arr2[2][3] //多维数组动态创建数组
C中直接声明数组需要明确数组的大小但是可以使用new来动态创建数组虽然这样数组也有固定的大小只是在运行期间可以确定需要多少元素后再创建制定大小数组。
int* pa new int[size];//size为运行时确定
delete [] pa;//不用时要释放C/CLI泛型
C#中具有泛型类型C/CLI中也具有泛型类型。
generic typename T
ref class Mylist
{
public:void Add(T obj);T GetAtIndex(int idx);
};//使用时制定泛型类型
MylistString^^ lists gcnew MylistString^();C中的泛型模板和.net中的泛型虽然功能很相似但是工作方式完全不同所以在C/CLR中都得到了支持。两者主要的不同之处有
模版是在编译时就实例化好的而泛型是在运行时仍然是泛型的模版支持特化、非类型模板参数和模版参数等而泛型不支持要简单的多泛型类型不能从类型参数继承而模板可以泛型不支持元编程泛型类型支持类型参数约束模板不支持。
托管数组
与C不同托管数组直接分配到堆上首gc的管理而且索引不再制定从某个地址偏移。并且要用Array关键字来声明。
arrayint^ arr1;
arrayIntVal^, 2^ arr2;//2维数组
//初始化
arrayint^ arr1 gcnew arrayint(3) { 1, 2, 3 };
arrayint^ arr2 gcnew arrayint {1, 2, 3};
arrayint^ arr3 {1,2,3};对于引用类型的数组实际上是句柄的数组。例如main函数int main(arraySystem::String^^ args)实际上是String的句柄数组。另外.net提供了for each循环来遍历数组与C#一样任何实现了IEnumberator接口的集合都可以使用for each
arrayint^ arr3 {1,2,3};for each (int s in arr3)
{Console::WriteLine(s);
}多维数组
与C不同多维数组的维数要在尖括号中定义且读取多维数组也要在一个方括号中添加索引。
arrayint, 2^ array2d gcnew arrayint, 2(3, 3);
array2d[1, 2] 3;
arrayint, 2^ array2d_1 {{1,2,3},{4,5,6},{7,8,9}
};Console::WriteLine(array2d_1[0,1]);ListT
在实际开发过程中更多的使用泛型集合类因为集合可以改变大小。
using namespace System::Collections::Generic;Listint^ lst gcnew Listint();
lst-Add(0);
lst-Add(1);
lst-Add(2);
Listint^ lst gcnew Listint(10);//指定容量SortedListString^, int^ sl gcnew SortedListString^, int();
sl-Add(a, 1044);STL/CLR
STL容器是标准C一部分提供了一系列高性能、可扩展的集合类。C/CLi提供了托管STL版本。使用方法与STL类似。
#include cliext/vector
using namespace System;
using namespace cliext;int main(arraySystem::String^^ args)
{vectordouble v1;for (int i 0; i 10; i){v1.push_back(i * 2);}for (vectordouble::iterator it v1.begin();it!v1.end(); it){Console::WriteLine(*it);}Console::WriteLine(程序结束);
}属性
在.net中一般不会公开字段而是公开属性。属性本身就是方法包含get和set。在C/CLI中支持两种属性标准量属性和索引属性。
标量属性
标量属性也就是最常见的属性将私有字段使用属性保护起来使用property来声明而且可以根据需要只实现get以满足只读属性的要求。
ref class Person
{
public:property String^ Name{String^ get(){return name;}void set(String^ value){name value;}}property int Age{int get(){return age;}void set(int value){age value;}}
private:String^ name;int age;
};int main(arraySystem::String^^ args)
{Person^ p gcnew Person();p-Name 小明;p-Age 10;Console::WriteLine({0}今年{1}岁, p-Name, p-Age);Console::WriteLine(程序结束);
}自动属性
在C#中是可以自动实现属性的如public int Order { set; get; } C/CLI中同样可以:property String^ Name。
属性继承
因为属性本质上就是方法所以可以实现虚属性以达到重写属性的目的。
public ref class Shape abstract
{
public:virtual property double Area;
};public ref class Circle:Shape
{
private:double r1;
public:virtual property double Area {double get() override {return Math::PI * r * r;}}
};属性索引
属性索引就是可以在对象上直接使用[]来访问其工作方式与标量属性相似只需要在属性名后面的方括中包含索引类型就可以
property double Name[int]这段代码定义的索引属性为Name其索引类型为long在get和set函数中的第一个参数必须为索引。
property double Name[int]
{double get(int idx){...}void set(int idx,double vlaue){...}
}double bal a1-Name[10];//使用如果使用defaut名称可以在对象上直接访问
ref class Account
{
private:Listint^ lst gcnew Listint();
public:Account(){lst-Add(1);lst-Add(2);lst-Add(3);lst-Add(4);lst-Add(5);lst-Add(6);}property int Value[int]{int get(int idx){return lst[idx];}}//使用default可以在对象上直接访问property int default[int]{int get(int idx){return lst[idx];}}
};int main(arraySystem::String^^ args)
{Account^ a gcnew Account();int s a-Value[0];int ss a[1];//使用default可以在对象上直接访问Console::WriteLine(s);Console::WriteLine(ss);Console::WriteLine(程序结束);
}