0Pricing
C# Academy · درس

التحويلات المعرّفة من المستخدم

أضيفوا عوامل التحويل الضمنية والصريحة

التحويلات المعرّفة من المستخدم درس مجاني في C# Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C# Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C# Academy 4 دروس في المجموع.

التحويلات المعرّفة من قبل المستخدم

تتيح C# للنوع تعريف كيفية تحويله إلى نوع آخر أو التحويل منه، باستخدام المعاملين implicit وexplicit. تحدث التحويلات الضمنية تلقائيًا، أما التحويلات الصريحة فتتطلب عملية تحويل صريحة.

تحويل ضمني

استخدم implicit operator عندما يكون التحويل آمنًا دائمًا ولا يسبب فقدانًا للمعلومات. ويطبّقه المصرّف تلقائيًا أينما كان النوع الهدف متوقعًا.

using System;

public struct Celsius
{
    public double Degrees;
    public Celsius(double d) { Degrees = d; }

    // Always safe: a Celsius is just a number
    public static implicit operator double(Celsius c) => c.Degrees;
}

public class Program
{
    public static void Main()
    {
        Celsius temp = new Celsius(21.5);
        double d = temp; // implicit, no cast needed
        Console.WriteLine(d);
    }
}

تحويل صريح

استخدم explicit operator عندما يمكن أن يؤدي التحويل إلى فقدان معلومات أو إلى فشل. ويجب على المستدعين كتابة عملية تحويل صريحة، للدلالة على قبولهم للمخاطر.

using System;

public struct Money
{
    public decimal Amount;
    public Money(decimal a) { Amount = a; }

    // Loses the fractional cents, so make it explicit
    public static explicit operator int(Money m) => (int)m.Amount;
}

public class Program
{
    public static void Main()
    {
        var m = new Money(19.99m);
        int dollars = (int)m; // explicit cast required
        Console.WriteLine(dollars);
    }
}

التحويل إلى نوعك

يمكن أن تسير التحويلات في الاتجاه الآخر أيضًا: من نوع آخر إلى نوعك. ينشئ المعامل implicit هنا قيمة Celsius من قيمة double خام.

using System;

public struct Celsius
{
    public double Degrees;
    public Celsius(double d) { Degrees = d; }

    public static implicit operator Celsius(double d) => new Celsius(d);

    public override string ToString() => Degrees + "C";
}

public class Program
{
    public static void Main()
    {
        Celsius t = 18.0; // double implicitly becomes Celsius
        Console.WriteLine(t);
    }
}

الضمني أم الصريح: اختيار الأنسب

القاعدة العامة: اجعل التحويل ضمنيًا فقط إذا كان لا يفقد البيانات ولا يسبب استثناءً مطلقًا. وإذا كان قد يفقد الدقة أو يسبب تجاوزًا أو يفشل، فاجعله صريحًا.

using System;

public struct Percentage
{
    public double Value; // 0..1
    public Percentage(double v) { Value = v; }

    // Safe and lossless -> implicit
    public static implicit operator double(Percentage p) => p.Value;
    // Could be out of range -> explicit
    public static explicit operator Percentage(double v) => new Percentage(v);
}

public class Program
{
    public static void Main()
    {
        double d = new Percentage(0.25);
        var p = (Percentage)0.5;
        Console.WriteLine(d + " " + p.Value);
    }
}

التحويلات بين الأنواع المخصصة

لا تقتصر التحويلات على الأنواع المضمنة. يمكنك التحويل بين نوعين من تعريفك، مثل التحويل من الإحداثيات القطبية إلى الإحداثيات الديكارتية.

using System;

public struct Cartesian
{
    public double X, Y;
    public Cartesian(double x, double y) { X = x; Y = y; }
    public override string ToString() => "(" + Math.Round(X, 2) + ", " + Math.Round(Y, 2) + ")";
}

public struct Polar
{
    public double R, Theta;
    public Polar(double r, double theta) { R = r; Theta = theta; }
    public static explicit operator Cartesian(Polar p)
        => new Cartesian(p.R * Math.Cos(p.Theta), p.R * Math.Sin(p.Theta));
}

public class Program
{
    public static void Main()
    {
        var c = (Cartesian)new Polar(1.0, 0.0);
        Console.WriteLine(c);
    }
}

التحويلات تتكامل مع المؤثرات

بمجرد توفر تحويل، تشارك القيمة في التعبيرات الخاصة بالنوع الهدف. يتيح التحويل الضمني إلى double استخدام نوعك مباشرةً في العمليات الحسابية.

using System;

public struct Meters
{
    public double Value;
    public Meters(double v) { Value = v; }
    public static implicit operator double(Meters m) => m.Value;
}

public class Program
{
    public static void Main()
    {
        var distance = new Meters(5);
        double doubled = distance * 2; // uses implicit conversion to double
        Console.WriteLine(doubled);
    }
}

تجنب التحويلات الضمنية المفاجئة

قد تخفي التحويلات الضمنية التي لا تكون آمنة بوضوح الأخطاء، لأن المترجم يطبقها بصمت. وعند الشك، فَضّل التحويل الصريح حتى تكون النية واضحة في الشيفرة.

using System;

public struct UserId
{
    public int Value;
    public UserId(int v) { Value = v; }
    // Explicit on purpose: an int is not always a valid id
    public static explicit operator UserId(int v) => new UserId(v);
    public static explicit operator int(UserId id) => id.Value;
}

public class Program
{
    public static void Main()
    {
        var id = (UserId)42;
        int raw = (int)id;
        Console.WriteLine(raw);
    }
}

مؤثرات التحويل هي static

مثل المؤثرات الأخرى، تكون مؤثرات التحويل public static. ويجب أن يكون أحد النوعين المشاركين بالضبط هو النوع الذي يعرّف المؤثر.

using System;

public struct Fahrenheit
{
    public double Degrees;
    public Fahrenheit(double d) { Degrees = d; }
    public static implicit operator Fahrenheit(double d) => new Fahrenheit(d);
    public static implicit operator double(Fahrenheit f) => f.Degrees;
    public override string ToString() => Degrees + "F";
}

public class Program
{
    public static void Main()
    {
        Fahrenheit f = 98.6;
        double d = f;
        Console.WriteLine(f + " = " + d);
    }
}

نوع تغليف عملي

تتألق التحويلات مع أنواع التغليف البسيطة التي تعزز نظام الأنواع دون تعقيد. في هذا المثال، يتحول NonEmptyString ضمنيًا إلى string، لكن إنشاؤه يتطلب تحويلًا صريحًا.

using System;

public struct NonEmptyString
{
    public string Value;
    public NonEmptyString(string v)
    {
        if (string.IsNullOrEmpty(v)) throw new ArgumentException("empty");
        Value = v;
    }
    public static explicit operator NonEmptyString(string s) => new NonEmptyString(s);
    public static implicit operator string(NonEmptyString s) => s.Value;
}

public class Program
{
    public static void Main()
    {
        var name = (NonEmptyString)"Ada";
        string s = name;
        Console.WriteLine(s);
    }
}

جرّب بنفسك

عرّف نوع تغليف يتضمن تحويلًا ضمنيًا إلى الخارج (آمنًا) وتحويلًا صريحًا إلى الداخل (بعد التحقق). لاحظ أي اتجاه يتطلب تحويلًا صريحًا.

using System;

public struct Ratio
{
    public double Value;
    public Ratio(double v)
    {
        if (v < 0 || v > 1) throw new ArgumentOutOfRangeException(nameof(v));
        Value = v;
    }
    public static implicit operator double(Ratio r) => r.Value; // always safe
    public static explicit operator Ratio(double v) => new Ratio(v); // may throw
}

public class Program
{
    public static void Main()
    {
        var half = (Ratio)0.5;   // explicit, validated
        double d = half;          // implicit, safe
        Console.WriteLine(d * 100 + "%");
    }
}

اختبار سريع

اختر نوع التحويل المناسب.

مراجعة

تتيح التحويلات المعرّفة من المستخدم لأنواعك العمل معًا بسلاسة.

  • implicit operator للتحويلات الآمنة دائمًا والخالية من فقدان البيانات.
  • explicit operator عندما يمكن فقدان البيانات أو قد يفشل التحويل.
  • يمكن أن تستهدف التحويلات أنواعًا مضمنة أو مخصصة، وفي كلا الاتجاهين.
  • تكون public static ويعرّفها أحد النوعين المشاركين.

الأسئلة الشائعة

هل درس «التحويلات المعرّفة من المستخدم» مجاني؟

نعم — نص درس «التحويلات المعرّفة من المستخدم» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C# Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C# Academy 4 دروس في المجموع.

ماذا ستتعلم في «التحويلات المعرّفة من المستخدم»؟

أضيفوا عوامل التحويل الضمنية والصريحة تتمرن على C# Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ C# Academy؟

لا تُشترط خبرة سابقة. C# Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «التحويلات المعرّفة من المستخدم»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس C# Academy هذا؟

نعم. كل درس في C# Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. تحميل عوامل الحساب الزائد
  2. تحميل عوامل المقارنة الزائد
  3. التحويلات المعرّفة من المستخدم
  4. أفضل ممارسات تحميل العوامل الزائد
← العودة إلى C# Academy