【C++ 】C++ 与 C#:using 关键字、命名空间及作用域解析符对比

C++ vs C#:using、命名空间、.::的一图三句速查

速查表(建议收藏)
特性 C++ C# 记忆口诀
引入整个命名空间 using namespace std; using System; 一样写
引入单个名字 using std::cout; ❌ 不支持 变量进类
类型别名 using Map = std::map<K,V>; using Map = Dictionary<K,V>; 右侧糖
作用域运算符 ::(能指全局) .(始终前缀) 双冒变点

1. using关键字:同名不同命

1.1 C++ 的三张面孔

cpp 复制代码
// ① 整包引入
#include <iostream>
using namespace std;          // 整包

// ② 精确引入
using std::cout;              // 单名
using std::endl;

// ③ 类型别名
#include <vector>
using IntVec = vector<int>;   // 别名

int main() {
    IntVec v{1,2,3};
    cout << v.size() << endl; // 单名引入,无需 std::
}

1.2 C# 的两张面孔

csharp 复制代码
// ① 整包引入
using System;
using System.Collections.Generic;

// ② 静态导入(整包静态成员)
using static System.Math;     // 只能"类"级,不能"单名"

class Program {
    static void Main() {
        Console.WriteLine(Sqrt(9)); // 直接 Sqrt
    }
}

1.3 反例:C# 没有"单名引入"

csharp 复制代码
namespace N {
    public static class Foo {
        public static void Bar() { }
    }
}

// 理想:using N.Foo.Bar;   // ❌ CS0138
// 现实:using static N.Foo; // √ 但 Bar 以外全进来

2. 命名空间:能放啥?

2.1 C++ ------ 什么都敢放

cpp 复制代码
namespace My {
    int       g = 42;           // 变量
    void foo() { }              // 函数
    class Cls { };              // 类型
}

int main() {
    My::foo();                  // 直接调
}

2.2 C# ------ 只能放"类型"

csharp 复制代码
namespace My {
    // int g;                   // ❌ CS0116
    // void foo() { }           // ❌ CS0116
    public static class Globals { // 变量进类
        public static int G = 42;
    }
}

class Program {
    static void Main() {
        Console.WriteLine(My.Globals.G);
    }
}

3. 作用域运算符::: vs .

C++任何名字前面只要出现 ::,编译器就进入"绝对路径"模式:从最外层作用域 开始一路找下去,中间可以跨命名空间、类、枚举、typedef/别名、模板 等。

下面把 :: 的 6 个高频场景一次列全,并给出"如果写成 . 会怎样"的对照,方便 C++ → C# 迁移时一眼看出差异。


  1. 全球定位:跳过局部遮蔽
cpp 复制代码
int value = 1;
void foo() {
    int value = 2;
    std::cout << ::value;   // 1,强制用全局
}

  1. 命名空间逐级下降
cpp 复制代码
namespace A::B {           // C++17 嵌套写法
    int x = 5;
}
int main() {
    std::cout << A::B::x;  // 5
}

C# 等价只能一路 .A.B.x


  1. 类/结构体静态成员
cpp 复制代码
struct Math {
    static double pi;
};
double Math::pi = 3.14;    // 类外定义时必须写 ::

C# 把静态成员直接写在类体里,访问时也是 .


  1. 嵌套类型(最常见的就是 iterator
cpp 复制代码
std::vector<int>::iterator it = v.begin();   // iterator 是 vector<int> 内部的类型别名

换成 C# 写法:

csharp 复制代码
List<int>.Enumerator it = v.GetEnumerator(); // 同样嵌套,但用 `.`

  1. 枚举类强作用域
cpp 复制代码
enum class Color { Red, Green };
Color c = Color::Red;        // 必须 ::

C# 枚举仍然是"弱作用域",直接 Color.Red


  1. 模板特化/静态断言等"编译期路径"
cpp 复制代码
template<typename T>
struct Foo {
    using type = T*;
};

Foo<int>::type p = nullptr;  // 取嵌套别名
static_assert(sizeof(Foo<double>::type) == 8);

C# 泛型没有 :: 语法,嵌套类型一律 .


一句话总结
:: 是 C++ 的"绝对路径分隔符",凡是需要从外层作用域开始精确寻名 的场景都会出现;

C# 没有"全局作用域"概念,也没有运算符重载之外的"类外定义"需求,因此统一用 . 即可。


4. 冷知识:编译器看谁

  • C++ 的 using 别名在模板实例化阶段仍可见;
  • C# 的 using 别名在生成 IL 时会被完全擦除,反射拿到的是原长名。

相关推荐
秋937 分钟前
Go语言(Golang)开发工程师全景解析:岗位职责·语言优势与使用场景·各城市薪资·发展前景·高考志愿填报(2026版)
开发语言·golang·高考
huangdong_1 小时前
1688商品图片采集技术解析:登录态处理与SKU图自动分类
开发语言
搬砖魁首2 小时前
基础能力系列 - 多线程2 - 条件变量
c++·rust·条件变量·原子类型·线程同步互斥
chase_my_dream2 小时前
C++ + SLAM 高频面试问题整理
开发语言·c++·面试
牛油果子哥q2 小时前
【C++ STL string 】C++ STL string 终极精讲:底层原理、内存机制、全套API、深浅拷贝、易错坑点与工程实战规范
数据库·c++
Cloud_Shy6182 小时前
解读《Effective Python 3rd Edition》:从练气到老魔(第五章 Item 30 - 32)
开发语言·人工智能·笔记·python·学习方法
天佑木枫2 小时前
15天Python入门系列 · 序
开发语言·python
宋拾壹3 小时前
同时添加多个类目
android·开发语言·javascript
凡人叶枫4 小时前
Effective C++ 条款04:确定对象被使用前已先被初始化
java·linux·开发语言·c++·嵌入式开发
不想写代码的星星4 小时前
std::move 根本不移动,就像老婆饼里没有老婆
c++