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

相关推荐
一起养小猫19 小时前
Flutter for OpenHarmony 实战:打造天气预报应用
开发语言·网络·jvm·数据库·flutter·harmonyos
安全二次方security²19 小时前
CUDA C++编程指南(7.25)——C++语言扩展之DPX
c++·人工智能·nvidia·cuda·dpx·cuda c++编程指南
xyq202419 小时前
Java 抽象类
开发语言
爱装代码的小瓶子19 小时前
【c++与Linux基础】文件篇(4)虚拟文件系统VFS
linux·开发语言·c++
疯狂的喵1 天前
C++编译期多态实现
开发语言·c++·算法
2301_765703141 天前
C++中的协程编程
开发语言·c++·算法
m0_748708051 天前
实时数据压缩库
开发语言·c++·算法
小魏每天都学习1 天前
【算法——c/c++]
c语言·c++·算法
lly2024061 天前
jQuery Mobile 表格
开发语言
惊讶的猫1 天前
探究StringBuilder和StringBuffer的线程安全问题
java·开发语言