C#: مساحات الأسماء واستخدامها
1. ما هو مجال الأسماء؟
مساحة الأسماء هي آلية تجميع منطقية تُستخدم لتنظيم الكود وتجنب تعارضات أسماء الأنواع. في المشاريع الكبيرة، قد تُعرِّف وحدات مختلفة فئات تحمل الاسم نفسه؛ وتوفر مساحات الأسماء مسارًا مُحدَّدًا للأنواع.
2. تعريف مساحة الاسم
استخدم الكلمة الرئيسية namespace لإعلان مساحة اسم، مع وضع الأنواع داخل الأقواس المتعرجة.
▶ مثال
namespace MyApp.Models
{
public class User
{
public string Name { get; set; }
public int Age { get; set; }
}
}
namespace MyApp.Services
{
public class UserService
{
public string GetInfo()
{
return "UserService is ready";
}
}
}
3. تداخل مساحات الأسماء
يمكن أن تكون مساحات الأسماء متداخلة، بحيث تكون مساحات الأسماء الداخلية مساحات فرعية للمساحات الخارجية. ويُعتبر الوصول باستخدام الترميز بالنقطة مكافئًا للهيكل المتداخل.
▶ مثال
namespace Company
{
namespace Products
{
namespace Electronics
{
public class Phone
{
public string Model { get; set; }
}
}
}
}
namespace Company.Products.Electronics
{
public class Tablet
{
public string Model { get; set; }
}
}
ينتمي كل من Company.Products.Electronics.Phone وCompany.Products.Electronics.Tablet إلى نفس مساحة الأسماء.
4. مساحات الأسماء على مستوى الملف (C# 10)
أدخلت لغة C# 10 مساحات الأسماء التي تقتصر على نطاق الملف، والتي تستخدم فاصلة منقوطة في نهايتها. ويقع الملف بأكمله تلقائيًا ضمن تلك المساحة، مما يقلل من التباعد في التداخل.
▶ مثال
namespace MyApp.Services;
public class EmailService
{
public void Send(string to)
{
System.Console.WriteLine($"Sending email to {to}");
}
}
Sending email to user@example.com
5. استخدام التوجيه
تقوم التوجيهية using باستيراد مساحة أسماء، مما يتيح لك استخدام أنواعها مباشرةً دون الحاجة إلى كتابة الاسم الكامل.
▶ مثال
using System;
namespace MyApp
{
class Program
{
static void Main()
{
Console.WriteLine("No need for System.Console");
Console.WriteLine(DateTime.Now.Year);
}
}
}
No need for System.Console
2026
6. استخدام الاسم المستعار
عندما يكون اسم الفضاء طويلاً جدًّا أو في حالة وجود تعارضات في أسماء الأنواع، يمكنك استخدام using ... = ... لإنشاء اسم مستعار.
▶ مثال
using Dict = System.Collections.Generic.Dictionary`<string, int>`;
using StringBuilder = System.Text.StringBuilder;
namespace MyApp
{
class Program
{
static void Main()
{
Dict scores = new Dict();
scores.Add("Alice", 95);
scores.Add("Bob", 87);
StringBuilder sb = new StringBuilder();
foreach (var pair in scores)
{
sb.AppendLine($"{pair.Key}: {pair.Value}");
}
System.Console.WriteLine(sb.ToString());
}
}
}
Alice: 95
Bob: 87
7. استخدام الكائنات الثابتة (C# 6)
يستورد using static العناصر الثابتة لنوع ما، مما يتيح لك استدعاءها دون الحاجة إلى ذكر اسم النوع.
▶ مثال
using static System.Console;
using static System.Math;
namespace MyApp
{
class Program
{
static void Main()
{
WriteLine($"PI = {PI}");
WriteLine($"Max = {Max(10, 20)}");
WriteLine($"Sqrt(144) = {Sqrt(144)}");
}
}
}
PI = 3.14159265358979
Max = 20
Sqrt(144) = 12
8. الاستخدام العام (C# 10)
إن تعريف global using في ملف واحد يجعل مساحة الأسماء متاحة في جميع الملفات ضمن المشروع بأكمله، مما يلغي الحاجة إلى تكرار using.
▶ مثال
global using System;
global using System.Collections.Generic;
global using System.Linq;
من الممارسات الشائعة وضع أوامر الاستخدام العامة في ملف GlobalUsings.cs من أجل الإدارة المركزية.
9. الاستخدامات الضمنية (C# 10)
يؤدي تمكين <ImplicitUsings>enable</ImplicitUsings> في ملف المشروع إلى قيام المشاريع التي تتبع نمط SDK بإضافة أوامر «using» عامة تلقائيًّا لمساحات الأسماء الشائعة الاستخدام.
▶ مثال
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>
تتضمن مشاريع وحدة التحكم تلقائيًا مساحات الأسماء التالية: System، System.Collections.Generic، System.IO، System.Linq، System.Threading، System.Threading.Tasks، إلخ.
10. استخدام واجهة IDisposable
يضمن البيان using أن الكائنات IDisposable تقوم بتحرير الموارد بشكل صحيح بعد استخدامها. كما يدعم C# 8 صيغة إعلان using.
▶ مثال
using System;
using System.IO;
namespace MyApp
{
class Program
{
static void Main()
{
using (var fs = new FileStream("test.txt", FileMode.Create))
{
byte[] data = System.Text.Encoding.UTF8.GetBytes("Hello");
fs.Write(data, 0, data.Length);
}
using var reader = new StreamReader("test.txt");
Console.WriteLine(reader.ReadToEnd());
}
}
}
Hello
يتم تحرير النموذج المحاط بأقواس متعرجة عند نهاية نطاقه؛ أما using var فيتم تحريره عند نهاية النطاق المحيط به.
11. تنظيم مساحات الأسماء في مكتبة فئات .NET
تنظم مكتبة فئات .NET الوظائف في مساحات أسماء فرعية تابعة لمساحة الاسم System.
▶ مثال
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace MyApp
{
class Program
{
static void Main()
{
ArrayList list = new ArrayList { 1, 2, 3 };
List````<string>```` names = new List````<string>```` { "Alice", "Bob" };
var upper = names.Select(n => n.ToUpper());
StringBuilder sb = new StringBuilder("Count: ");
sb.Append(names.Count);
Console.WriteLine(sb.ToString());
}
}
}
Count: 2
| مساحة الاسم | الغرض |
|---|---|
System |
الأنواع الأساسية (Console، DateTime، Math، إلخ) |
System.IO |
عمليات الملفات والدفق |
System.Collections |
المجموعات غير العامة (ArrayList، Hashtable) |
System.Collections.Generic |
المجموعات العامة (List<T>، Dictionary`<K,V>`) |
System.Linq |
امتدادات استعلامات LINQ |
System.Text |
معالجة السلاسل (StringBuilder، الترميز) |
System.Threading |
العمليات المتوازية والتزامن |
System.Threading.Tasks |
البرمجة غير المتزامنة (Task، Task<T>) |
❓ أسئلة شائعة
📖 ملخص
- يتم تعريف مساحات الأسماء باستخدام
namespace، مع دعم التداخل بين الأقواس المتعرجة وتدوين النقطة - تستورد التوجيهية
usingمساحة أسماء، مما يلغي الحاجة إلى الأسماء المؤهلة بالكامل using Alias = FullTypeNameيحل تعارضات الأسماء أو يبسط الأسماء الطويلةusing staticيستورد العناصر الثابتة لنوع ما من أجل الاستدعاء المباشرglobal usingيُطبق على مستوى المشروع بأكمله، مما يمنع التكرار في كل ملف على حدة- مساحة الأسماء على مستوى الملف
namespace X;تقلل من مستويات التبعية - تُدرج الاستخدامات الضمنية مساحات الأسماء الشائعة تلقائيًا من خلال إعدادات المشروع
usingتُستخدم العبارات/الإعلانات لإطلاق الموارد التي تتبع واجهة IDisposable- تنقسم مكتبة فئات .NET إلى مساحات أسماء فرعية تابعة لـ System حسب الوظيفة
📝 تمارين
- قم بإنشاء فئة
Teacherفي مساحة أسماء متداخلة من مستويينSchool.Teachers، وقم بإنشاء مثيل لها فيMain - استخدم الاسم المستعار
usingلإنشاء اسم مستعار مختصر لـSystem.Collections.Generic.List``<string>، ثم استخدمه لإنشاء قائمة وإضافة عناصر إليها وعرضها - استخدم
using static System.MathلاستدعاءSqrtوAbsوRoundمباشرةً، وعرض النتائج - قم بإنشاء ملف
GlobalUsings.csيحتوي على إعلاناتglobal usingلـSystemوSystem.IOوSystem.Linq، ثم احذف هذه الاستخدامات في ملف آخر للتحقق من أنها تعمل - استخدم كل من أسلوب العبارة بين الأقواس المتعرجة
usingوأسلوب الإعلانusing varللكتابة في ملف باستخدامStreamWriter، ولاحظ الفرق