cocos转unity笔记(一)从C++到C#

C#的foreach

和C++11的类似,好像C++就是反向吸收C#/Java特性的吧。嘛,这个不重要
写法是差不多的的,C++是

1
for (T item : container) { }

C#是

1
foreach (T item in container) { }

在C++里,容器container必须有begin()和end()方法,并且其迭代器有重载++运算符
在C#里,容器container必须是一个可枚举类型,即继承并实现了IEnumerable接口,对应的枚举数继承IEnumerator接口

C#的容器

在C++里最常用的容器是vector和map,C#也有类似stl的泛型容器

要用的话要在开头加一条using:

1
using System.Collections.Generic;

主要对应关系如下表:

C++C#
std::vector<int>List<int>
std::map<int, string>Dictionary<int, string>

C++的双向队列std::deque暂时没有在C#中找到对应的容器,C#只有Queue和Stack,不过我还是想要Deque哇

vector vs List

当然,C#的List也是个对象,不像vector定义完就可以用,List定义完必须要new之后才能用

对应的方法如下表(这里仅仅列出了我个人比较常用的):

vector<T>::iteratorList<T>.Enumerator

C++C#
vector<T>::push_back(val)List<T>.Add(val)
vector<T>::erase(itr)List<T>.Remove(val)
vector<T>::clear()List<T>.Clear()
vector<T>::size()List<T>.Count
std::sort(v.begin(), v.end(), cmp)List<T>.Sort(cmp)

关于排序,C++的比较函数一般这样写

1
2
3
4
5
// 如果val1应该排在val2前面则返回true,否则返回false
bool cmp(const T& val1, const T& val2)
{
return val1 < val2;
}

C#则有点不一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 如果val1应该排在val2前面则返回-1,后面则返回1,相等的话返回0
private static int cmp(T val1, T val2)
{
int ret = 0;
if (val1 > val2)
{
ret = 1;
}
if (val1 < val2)
{
ret = -1;
}
return ret;
}

如果基类型是自定义的类,还可以使类继承IComparable接口,重写CompareTo()方法,就可以直接调用List.Sort()方法而不用参数了

好奇的地方

其实C#还有一个ArrayList类型,其实就是List<object>,网上关于这个的看法几乎都是:相比List<T>不是类型安全的,而且涉及基本类型的存储时会发生装箱和拆箱的操作,所以效率上会有比较大的问题。

然而我发现List<T>里的T如果不是基本类型而是我们手动new出来的对象,List<T>的存储效率居然比ArrayList(List<object>)要低20%左右。

还有关于Listforeach,网上的说法普遍认为foreach的效率不如普通的for,这个好像在某个版本的C#之后就已经把这个性能问题解决了。

关于这两个话题,过几天我再写一篇文章整理下我的测试结果。

map vs Dictionary

C++C#
内部使用红黑树内部使用哈希表
map[key] = valuemap[key] = value
map.erase(iterator)map.Remove(key)
map.clear()map.Clear()
没有现成的方法map.ContainsKey(key)
没有现成的方法map.ContainsValue(value)
map.size()map.Count

关于排序,和List类似,比较函数的写法都是一样的。

多啰嗦几句有关于遍历的东西,C++的map遍历一般这样写:

1
2
3
4
5
6
7
8
9
10
11
for (auto i = map.begin(); i != map.end(); ++i)
{
int key = i->first;
int value = i->second;
}
// 或者使用C++11的range-based for特性
for (auto& item : map)
{
int key = item.first;
int value = item.second;
}

C#里一般这样

1
2
3
4
5
foreach (var item in map)
{
int key = item.key;
int value = item.value;
}

总结

这里写的东西都是平常用的比较多的,而且我才刚开始学习C#,所以有关C#的部分难免会有错误,请尽量在评论区指出~
这种文章并不是API文档之类的可供查阅的东西,只是我个人的学习笔记啦