【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 时会被完全擦除,反射拿到的是原长名。

相关推荐
晗夜未央34 分钟前
任务队列反复失败,先分清重试、阻塞和结果待核对
开发语言·javascript
熊猫钓鱼>_>37 分钟前
四种书签,一条时间线:一个读书 App 的记忆颗粒与它的边界案例【鸿蒙心迹】
开发语言·华为·ai编程·harmonyos·鸿蒙·openharmony·鸿蒙pc
Fuyo_11191 小时前
C++ AVL树保姆级详解:从平衡因子到四大旋转机制
java·c++·算法
努力努力再努力wz1 小时前
【Lua 入门系列】Lua 函数深入理解:函数对象、多返回值、可变参数、闭包、递归与尾调用优化
开发语言·lua
飞浪纪元[FWC–FE]2 小时前
从零到一键绿:Qt 5.14.2 + VS2019 开发环境搭建、Kit 套件配置与构建错误修复完全手册
开发语言·qt
Wang's Blog2 小时前
Java 项目实战:交友项目 - 联系人列表
java·开发语言·交友
傲世仙尊2 小时前
继承-类设计层次复用切片转换与菱形继承的死结
c++
我命由我123452 小时前
访客系统形式(有用户概念、无用户概念)
java·开发语言·前端·javascript·python·产品运营·产品经理
架构师伯子明2 小时前
FFmpeg C++学习(一):编译和demo
开发语言·c++·学习
海域云SeaArea_2 小时前
Windows Server 2008 R2 从零安装 IIS7.5(二):php.ini 配置
开发语言·windows·php