سؤال

في C#، ما الذي يجعل الحقل مختلفًا عن الخاصية، ومتى يجب استخدام الحقل بدلاً من الخاصية؟

هل كانت مفيدة؟

المحلول

وخصائص تعرض المجالات. يجب (دائما تقريبا) أن تبقى الحقول الخاص لفئة والوصول إليها عن طريق الحصول على وتعيين خصائص. توفر خصائص مستوى من التجريد مما يسمح لك لتغيير الحقول في حين لا تؤثر على الطريقة خارجية يتم الوصول إليها عن طريق الأشياء التي تستخدم صفك.

public class MyClass
{
    // this is a field.  It is private to your class and stores the actual data.
    private string _myField;

    // this is a property. When accessed it uses the underlying field,
    // but only exposes the contract, which will not be affected by the underlying field
    public string MyProperty
    {
        get
        {
            return _myField;
        }
        set
        {
            _myField = value;
        }
    }

    // This is an AutoProperty (C# 3.0 and higher) - which is a shorthand syntax
    // used to generate a private field for you
    public int AnotherProperty{get;set;} 
}

وKent يشير إلى أن ليس مطلوبا من خصائص لتغليف المجالات، فإنها يمكن أن تفعل الحساب على غيرها من المجالات، أو تخدم أغراضا أخرى.

وGSS يشير إلى أنه يمكنك أيضا القيام منطق آخر، مثل التحقق من صحة، عند الوصول الممتلكات، وميزة أخرى مفيدة.

نصائح أخرى

ويقول

وجوه الموجه مبادئ البرمجة التي والعمل الداخلي من فئة يجب أن تكون مخفية عن العالم الخارجي. إذا كنت فضح حقل كنت في جوهر تعريض تنفيذ الداخلي للفئة. وبالتالي فإننا التفاف المجالات مع خصائص (أو الأساليب في حالة جاوة) ليعطينا القدرة على تغيير التنفيذ دون كسر الشفرة يعتمدون علينا. كما نرى يمكن أن نضع المنطق في الملكية يسمح لنا أيضا لإجراء التحقق من صحة المنطق الخ واذا كنا في حاجة إليها. C # 3 لديه فكرة ربما الخلط بين autoproperties. وهذا يسمح لنا ببساطة لتحديد الملكية وسوف مترجم C # 3 توليد حقل خاص بالنسبة لنا.

public class Person
{
   private string _name;

   public string Name
   {
      get
      {
         return _name;
      }
      set
      {
         _name = value;
      }
   }
   public int Age{get;set;} //AutoProperty generates private field for us
}

وهناك فرق هام هو أن واجهات يمكن أن يكون لها خصائص ولكن ليس المجالات. هذا، بالنسبة لي، يؤكد أن خصائص ينبغي أن تستخدم لتحديد الواجهة العمومية فئة، بينما من المفترض المجالات لاستخدامها في أعمال خاصة، الداخلية للفئة. كقاعدة أنا نادرا إنشاء حقول العامة وبالمثل أنا نادرا ما خلق خصائص غير العامة.

سأعطيك بضعة أمثلة لاستخدام الخصائص التي قد تؤدي إلى تحول التروس:

  • التهيئة البطيئة: إذا كان لديك خاصية لكائن يكون تحميله مكلفًا، ولكن لا يمكن الوصول إليه كثيرًا في عمليات التشغيل العادية للتعليمات البرمجية، فيمكنك تأخير تحميله عبر الخاصية.بهذه الطريقة، يكون موجودًا هناك فقط، ولكن في المرة الأولى التي تحاول فيها وحدة أخرى استدعاء هذه الخاصية، فإنها تتحقق مما إذا كان الحقل الأساسي خاليًا - إذا كان كذلك، فإنها تمضي قدمًا وتحميله، غير معروف لوحدة الاستدعاء.يمكن أن يؤدي هذا إلى تسريع عملية تهيئة الكائن بشكل كبير.
  • تتبع القذرة: الذي تعلمته بالفعل من بلدي السؤال الخاص هنا على StackOverflow.عندما يكون لدي الكثير من الكائنات التي قد تتغير قيمها أثناء التشغيل، يمكنني استخدام الخاصية لتتبع ما إذا كانت بحاجة إلى حفظها مرة أخرى في قاعدة البيانات أم لا.إذا لم تتغير خاصية واحدة للكائن، فلن يتم التعثر في علامة IsDirty، وبالتالي ستتخطى وظيفة الحفظ هذه العلامة عند تحديد ما يجب العودة إلى قاعدة البيانات.

واستخدام خصائص، يمكنك رمي حدث، عندما يتم تغيير قيمة العقار (ويعرف أيضا باسم. PropertyChangedEvent) أو قبل أن يتم تغيير قيمة لدعم الإلغاء.

وهذا غير ممكن مع (وصول مباشر إلى) المجالات.

public class Person {
 private string _name;

 public event EventHandler NameChanging;     
 public event EventHandler NameChanged;

 public string Name{
  get
  {
     return _name;
  }
  set
  {
     OnNameChanging();
     _name = value;
     OnNameChanged();
  }
 }

 private void OnNameChanging(){
   EventHandler localEvent = NameChanging;
   if (localEvent != null) {
     localEvent(this,EventArgs.Empty);
   }
 }

 private void OnNameChanged(){
   EventHandler localEvent = NameChanged;
   if (localEvent != null) {
     localEvent(this,EventArgs.Empty);
   }
 }
}

حيث أن العديد منهم قد أوضحوا إيجابيات وسلبيات تقنية Properties و Field, ، لقد حان الوقت للدخول في أمثلة في الوقت الفعلي.

1.تسمح لك الخصائص بتعيين مستوى الوصول للقراءة فقط

النظر في حالة dataTable.Rows.Count و dataTable.Columns[i].Caption.يأتون من الفصل DataTable وكلاهما عام بالنسبة لنا.الفرق في مستوى الوصول إليهم هو أننا لا نستطيع تحديد القيمة لهم dataTable.Rows.Count ولكن يمكننا القراءة والكتابة ل dataTable.Columns[i].Caption.هل يمكن ذلك من خلال Field؟لا!!!يمكن القيام بذلك مع Properties فقط.

public class DataTable
{
    public class Rows
    {       
       private string _count;        

       // This Count will be accessable to us but have used only "get" ie, readonly
       public int Count
       {
           get
           {
              return _count;
           }       
       }
    } 

    public class Columns
    {
        private string _caption;        

        // Used both "get" and "set" ie, readable and writable
        public string Caption
        {
           get
           {
              return _caption;
           }
           set
           {
              _caption = value;
           }
       }       
    } 
}

2.العقارات في PropertyGrid

ربما كنت قد عملت مع Button في فيجوال ستوديو.خصائصه مبينة في PropertyGrid يحب Text,Name إلخ.عندما نقوم بسحب وإسقاط زر، وعندما ننقر على الخصائص، فإنه سيجد الفئة تلقائيًا Button والمرشحات Properties وإظهار ذلك في PropertyGrid (أين PropertyGrid لن تظهر Field رغم أنها عامة).

public class Button
{
    private string _text;        
    private string _name;
    private string _someProperty;

    public string Text
    {
        get
        {
           return _text;
        }
        set
        {
           _text = value;
        }
   } 

   public string Name
   {
        get
        {
           return _name;
        }
        set
        {
           _name = value;
        }
   } 

   [Browsable(false)]
   public string SomeProperty
   {
        get
        {
           return _someProperty;
        }
        set
        {
           _someProperty= value;
        }
   } 

في PropertyGrid, ، الخصائص Name و Text سوف تظهر، ولكن لا SomeProperty.لماذا؟؟؟لأن الخصائص يمكن أن تقبل صفات.لا تظهر في حالة حيث [Browsable(false)] هو زائف.

3.يمكن تنفيذ البيانات داخل الخصائص

public class Rows
{       
    private string _count;        


    public int Count
    {
        get
        {
           return CalculateNoOfRows();
        }  
    } 

    public int CalculateNoOfRows()
    {
         // Calculation here and finally set the value to _count
         return _count;
    }
}

4.يمكن استخدام الخصائص فقط في Binding Source

مصدر ملزم يساعدنا على تقليل عدد أسطر التعليمات البرمجية. Fields لا يتم قبولها من قبل BindingSource.يجب أن نستعمل Properties من أجل هذا.

5.وضع تصحيح الأخطاء

اعتبر أننا نستخدم Field لعقد قيمة.في مرحلة ما، نحتاج إلى تصحيح الأخطاء والتحقق من المكان الذي تصبح فيه القيمة فارغة لهذا الحقل.سيكون من الصعب القيام بذلك عندما يكون عدد أسطر التعليمات البرمجية أكثر من 1000.في مثل هذه الحالات يمكننا استخدامها Property ويمكن ضبط وضع التصحيح بالداخل Property.

   public string Name
   {
        // Can set debug mode inside get or set
        get
        {
           return _name;
        }
        set
        {
           _name = value;
        }
   }

الاختلافات - الاستخدامات (متى ولماذا)

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

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

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

إذا كنت أكتب مكتبة فئة مصممة للاستهلاك واسع (مثل برنامج .NET Framework، والذي يستخدم من قبل الملايين من الناس)، الذي يمكن أن يكون مشكلة. ومع ذلك، إذا كنت تكتب فئة يستخدم داخليا داخل قاعدة رمز صغير (ويقول <= 50 K خطوط)، انها في الحقيقة ليست صفقة كبيرة، لأنه لا يمكن لأحد أن تتأثر سلبا التغييرات. في هذه الحالة هو في الحقيقة مجرد يأتي الى تفضيل شخصي.

وخصائص تدعم الوصول غير المتماثلة، أي هل يمكن أن يكون إما جالبة واضعة أو مجرد واحد من اثنين. وبالمثل خصائص تدعم الوصول الفردي للجالبة / اضع. الحقول دائما متماثل، أي يمكنك دائما الحصول على كل من وتعيين القيمة. الاستثناء لهذا هو مجال للقراءة فقط والتي من الواضح لا يمكن تعيين بعد التهيئة.

وقد تعمل خصائص لفترة طويلة جدا، ولها آثار جانبية، وربما حتى رمي الاستثناءات. الحقول بسرعة، مع عدم وجود آثار جانبية، وسوف رمي أبدا الاستثناءات. بسبب الآثار الجانبية خاصية قد ترجع قيمة مختلفة عن كل مكالمة (كما قد يكون الحال بالنسبة لDateTime.Now، أي DateTime.Now ليست دائما يساوي DateTime.Now). الحقول دوما بإرجاع نفس القيمة.

والحقول يمكن أن تستخدم لمعلمات من أصل / المرجع، قد خصائص لا. خصائص تدعم منطق إضافية - وهذا يمكن أن تستخدم لتنفيذ تحميل كسول من بين أمور أخرى

.

وخصائص تدعم مستوى من التجريد عن طريق التغليف بكل ما يعني الحصول على / تعيين القيمة.

وخصائص استخدام في معظم / جميع الحالات، ولكن في محاولة لتجنب الآثار الجانبية.

في الخلفية يتم تصنيف خاصية في الأساليب. لذلك يتم تصنيف خاصية Name إلى get_Name() وset_Name(string value). يمكنك ان ترى هذا إذا كنت تدرس التعليمات البرمجية المترجمة. حتى لا يكون هناك (جدا) أداء صغير فوق عند استخدامها. عادة سوف دائما استخدام الخاصية إذا كنت فضح حقل إلى الخارج، وكثيرا ما كنت سوف تستخدم داخليا إذا ما عليك القيام به التحقق من القيمة.

وعندما تريد المتغير الخاص (حقل) لتكون في متناول كائن من الفئة الخاصة بك من الفئات الأخرى تحتاج إلى إنشاء خصائص تلك المتغيرات.

وعلى سبيل المثال إذا كان لدي المتغيرات يدعى "الهوية" و "اسم" والذي هو الخاص ولكن قد يكون هناك الحالة التي يكون فيها هذا المتغير يحتاج لعملية القراءة / الكتابة خارج الصف. في هذه الحالة، يمكن أن الملكية مساعدتي للحصول على هذا المتغير لقراءة / كتابة وهذا يتوقف على الحصول على / مجموعة محددة للممتلكات. خاصية يمكن أن تكون للقراءة فقط / writeonly / للقراءة والكتابة على حد سواء.

وهنا هو التجريبي

class Employee
{
    // Private Fields for Employee
    private int id;
    private string name;

    //Property for id variable/field
    public int EmployeeId
    {
       get
       {
          return id;
       }
       set
       {
          id = value;
       }
    }

    //Property for name variable/field
    public string EmployeeName
    {
       get
       {
          return name;
       }
       set
       {
          name = value;
       }
   }
}

class MyMain
{
    public static void Main(string [] args)
    {
       Employee aEmployee = new Employee();
       aEmployee.EmployeeId = 101;
       aEmployee.EmployeeName = "Sundaran S";
    }
}

السؤال الثاني هنا، "متى يجب استخدام الحقل بدلاً من الخاصية؟"، تم التطرق إليه بإيجاز فقط هذه الإجابة الأخرى ونوعا ما هذه ايضا, ، ولكن ليس الكثير من التفاصيل حقًا.

بشكل عام، جميع الإجابات الأخرى صحيحة حول التصميم الجيد:تفضل تعريض الخصائص على تعريض الحقول.بينما ربما لن تفعل ذلك بانتظام تجد نفسك تقول "رائع، تخيل كم ستكون الأمور أسوأ لو أنني جعلت هذا حقلاً بدلاً من عقار"، إنه بكثير من النادر أن تفكر في موقف تقول فيه "رائع، الحمد لله أنني استخدمت حقلاً هنا بدلاً من عقار."

ولكن هناك ميزة واحدة تتمتع بها الحقول على الخصائص، وهي قدرتها على استخدامها كمعلمات "ref" / "out".لنفترض أن لديك طريقة بالتوقيع التالي:

public void TransformPoint(ref double x, ref double y);

وافترض أنك تريد استخدام هذه الطريقة لتحويل مصفوفة تم إنشاؤها على النحو التالي:

System.Windows.Point[] points = new Point[1000000];
Initialize(points);

أعتقد أن هذه هي أسرع طريقة للقيام بذلك، منذ ذلك الحين X و ي هي خصائص:

for (int i = 0; i < points.Length; i++)
{
    double x = points[i].X;
    double y = points[i].Y;
    TransformPoint(ref x, ref y);
    points[i].X = x;
    points[i].Y = y;
}

وهذا سيكون جيدًا جدًا!ما لم تكن لديك قياسات تثبت خلاف ذلك، فلا يوجد سبب لرمي الرائحة الكريهة.لكنني أعتقد أنه ليس من المضمون تقنيًا أن تكون بهذه السرعة:

internal struct MyPoint
{
    internal double X;
    internal double Y;
}

// ...

MyPoint[] points = new MyPoint[1000000];
Initialize(points);

// ...

for (int i = 0; i < points.Length; i++)
{
    TransformPoint(ref points[i].X, ref points[i].Y);
}

القيام ببعض قياسات بنفسي، يستغرق الإصدار الذي يحتوي على حقول حوالي 61% من الوقت مثل الإصدار الذي يحتوي على خصائص (.NET 4.6، Windows 7، x64، وضع الإصدار، لا يوجد مصحح أخطاء مرفق).كلما كانت أكثر تكلفة TransformPoint تصبح الطريقة أقل وضوحًا ويصبح الفرق.لتكرار ذلك بنفسك، قم بتشغيل السطر الأول مع التعليق عليه وعدم التعليق عليه.

حتى لو لم تكن هناك فوائد أداء لما سبق، فهناك أماكن أخرى قد تكون فيها القدرة على استخدام معلمات ref وout مفيدة، كما هو الحال عند استدعاء متشابكة أو متقلب عائلة الأساليب. ملحوظة:في حال كان هذا جديدًا بالنسبة لك، فإن Volatile هي في الأساس طريقة للحصول على نفس السلوك الذي يقدمه volatile الكلمة الرئيسية.على هذا النحو، مثل volatile, ، فهو لا يحل جميع مشاكل سلامة الخيط بطريقة سحرية كما يوحي اسمه بذلك.

بالتأكيد لا أريد أن أبدو وكأنني أدعو إلى الذهاب "أوه ، يجب أن أبدأ في فضح الحقول بدلاً من الخصائص". النقطة المهمة هي أنه إذا كنت بحاجة إلى استخدام هؤلاء الأعضاء بانتظام في المكالمات التي تأخذ معلمات "المرجع" أو "خارج" ، خاصةً على شيء قد يكون نوعًا بسيطًا من القيمة ، من غير المحتمل أن يحتاج إلى أي من عناصر الخصائص ذات القيمة المضافة ، يمكن تقديم حجة.

وكذلك خصائص تسمح لك لاستخدام المنطق عند وضع القيم.

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

وميزة مفيدة حقا.

إذا كنت تنوي استخدام الأوليات موضوع كنت اضطر لاستخدام المجالات. يمكن خصائص كسر كود الخيوط الخاصة بك. وبصرف النظر عن ذلك، ما كوري قال هو الصحيح.

(وهذا ينبغي أن يكون حقا للتعليق، ولكن لا أستطيع أن تكتب تعليقا، لذلك يرجى عذر إذا لم يكن بالشكل المناسب وظيفة).

وعملت مرة واحدة في المكان الذي كانت الممارسة الموصى بها لاستخدام حقول العامة بدلا من خصائص عندما هزم الملكية يعادل سيكون فقط تم الوصول إلى حقل، كما في:

get { return _afield; }
set { _afield = value; }

وكان تفكيرهم أن المجال العام يمكن تحويلها إلى خاصية في وقت لاحق في المستقبل إذا لزم الأمر. وبدا غريبا بعض الشيء بالنسبة لي في ذلك الوقت. اذا حكمنا من خلال هذه الوظائف، يبدو أن ليست كثيرة هنا ستوافق أيضا. ما قد قلته في محاولة لتغيير الأمور؟

وتحرير: وأود أن أضيف أن كل رمز قاعدة في هذا المكان تم إعداده في نفس الوقت، لذلك قد يعتقد أن تغيير الواجهة العمومية من الطبقات (عن طريق تغيير حقل العام إلى خاصية) ليست مشكلة .

ومن الناحية الفنية، وأنا لا أعتقد أن هناك فرقا، لأن الخصائص هي مغلفة قاب الحقول التي تم إنشاؤها من قبل المستخدم أو تلقائيا إنشاؤها من قبل غرض compiler.The من خصائص غير لفرض encapsuation ولتقديم مثل طريقة خفيفة الوزن خاصية. انها مجرد عادة سيئة لاعلان المجالات مثل الجمهور، ولكن ليس لديها أي مشاكل.

هذه الصفحة على MSDN لديها مقارنة ونصائح حول أي واحد لاستخدام في الحالات التالية:

https://msdn.microsoft.com /en-us/library/9d65as2e(v=vs.90).aspx

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

  class SomeClass
  {
     int numbera; //Field

     //Property 
    public static int numbera { get; set;}

  }

وخصائص تلخص المجالات، مما يتيح لك لأداء معالجة إضافية على القيمة التي سيتم تحديدها أو استردادها. ومن عادة افراط في استخدام خصائص إذا كنت لن نفعل أي قبل أو تحليل نتائج على قيمة حقل.

والمنظمة البحرية الدولية، خصائص ليست سوى "SetXXX ()" "GetXXX ()" وظائف / طرق / واجهات أزواج كنا من قبل، لكنها أكثر إيجازا وأنيقة.

يتم تعيين

والمجالات خاصة تقليديا عن طريق وسائل جالبة واضعة. من أجل أقل رمز يمكنك استخدام خصائص لتحديد الحقول بدلا من ذلك.

وعندما يكون لديك فئة وهي "سيارة". خصائص واللون والشكل ..

وأين كحقول هي متغيرات محددة في نطاق فئة.

من ويكيبيديا -- البرمجة الشيئية:

البرمجة الشيئية (OOP) هي نموذج برمجة يعتمد على مفهوم "الكائنات"، وهي هياكل بيانات تحتوي على البيانات على شكل حقول, ، والمعروفة غالبًا بالسمات؛و الكود، في شكل إجراءات، تُعرف غالبًا بالطرق. (تم اضافة التأكيدات)

تعد الخصائص في الواقع جزءًا من سلوك الكائن، ولكنها مصممة لمنح مستهلكي الكائن وهم/تجريد العمل مع بيانات الكائن.

تصميمي للحقل هو أن الحقل يحتاج إلى تعديل فقط من خلال الأصل، ومن ثم الفئة.النتيجة أن يصبح المتغير خاصًا، ثم لأتمكن من إعطاء الحق في قراءة الفئات/الطرق خارجًا، أذهب من خلال نظام الملكية باستخدام Get فقط.يتم بعد ذلك استرداد الحقل بواسطة الخاصية ويكون للقراءة فقط!إذا كنت ترغب في تعديله، فيجب عليك المرور عبر طرق (على سبيل المثال المنشئ) وأجد أنه بفضل هذه الطريقة التي تجعلك آمنًا، لدينا تحكم أفضل في الكود الخاص بنا لأننا "نحدد الحافة".يمكن للمرء دائمًا أن يضع كل شيء علنًا، لذلك كل حالة محتملة، ومفهوم المتغيرات/الطرق/الفئات وما إلى ذلك ...في رأيي هو مجرد مساعدة لتطوير وصيانة الكود.على سبيل المثال، إذا استأنف شخص ما رمزًا به حقول عامة، فيمكنه فعل أي شيء وبالتالي أشياء "غير منطقية" فيما يتعلق بالهدف، ومنطق سبب كتابة الكود.إنها وجهة نظري.

عندما أستخدم نموذجًا كلاسيكيًا لحقل خاص/خصائص عامة للقراءة فقط، لـ 10 حقول خاصة، يجب أن أكتب 10 خصائص عامة!يمكن أن يكون الرمز كبيرًا جدًا بشكل أسرع.لقد اكتشفت أداة الضبط الخاصة والآن أستخدم فقط الخصائص العامة مع أداة الضبط الخاصة.يقوم الواضع بإنشاء حقل خاص في الخلفية.

ولهذا السبب كان أسلوبي في البرمجة الكلاسيكية القديمة هو:

public class MyClass
{
 private int _id;
 public int ID { get { return _id; } }
 public MyClass(int id)
 {
  _id = id;
 }
}

أسلوبي الجديد في البرمجة:

public class MyClass
{
 public int ID { get; private set; }
 public MyClass(int id)
 {
  ID = id;
 }
}

والحقول هي المتغيرات في الطبقات. الحقول البيانات التي يمكنك تغليف من خلال استخدام معدلات الوصول.

وخصائص متشابهة إلى الحقول حيث أنها تحدد الدول والبيانات المرتبطة كائن.

وعلى عكس حقل خاصية لديها بناء جملة خاص يتحكم كيف يمكن لشخص يقرأ البيانات ويكتب البيانات، وتعرف هذه باسم الحصول على وتعيين المشغلين. ويمكن في كثير من الأحيان منطق مجموعة أن تستخدم للقيام التحقق من الصحة.

الخصائص هي نوع خاص من أعضاء الفئة، في الخصائص نستخدم طريقة Set أو Get محددة مسبقًا. يستخدمون أدوات الوصول التي يمكننا من خلالها قراءة قيم الحقول الخاصة أو كتابتها أو تغييرها.

على سبيل المثال، دعونا نأخذ فئة اسمها Employee, ، مع حقول خاصة للاسم والعمر ومعرف_الموظف.لا يمكننا الوصول إلى هذه الحقول من خارج الفصل، لكن يمكننا الوصول إلى هذه الحقول الخاصة من خلال الخصائص.

لماذا نستخدم الخصائص؟

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

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

  • لا ينبغي أن يكون المعرف -ve.
  • لا يمكن تعيين الاسم إلى قيمة فارغة
  • يجب قراءة علامة المرور فقط.
  • إذا كان اسم الطالب مفقودًا فلا يجب إرجاع أي اسم.

لإزالة هذه المشكلة نستخدم طريقة Get and set.

// A simple example
public class student
{
    public int ID;
    public int passmark;
    public string name;
}

public class Program
{
    public static void Main(string[] args)
    {
       student s1 = new student();
       s1.ID = -101; // here ID can't be -ve
       s1.Name = null ; // here Name can't be null
    }
}

الآن نأخذ مثالاً على طريقة get and set

public class student
{
    private int _ID;
    private int _passmark;
    private string_name ;
    // for id property
    public void SetID(int ID)
    {
        if(ID<=0)
        {
            throw new exception("student ID should be greater then 0");
        }
        this._ID = ID;
    }
    public int getID()
    {
        return_ID;
    }
}
public class programme
{
    public static void main()
    {
        student s1 = new student ();
        s1.SetID(101);
    }
    // Like this we also can use for Name property
    public void SetName(string Name)
    {
        if(string.IsNullOrEmpty(Name))
        {
            throw new exeception("name can not be null");
        }
        this._Name = Name;
    }
    public string GetName()
    {
        if( string.IsNullOrEmpty(This.Name))
        {
            return "No Name";
        }
        else
        {
            return this._name;
        }
    }
        // Like this we also can use for Passmark property
    public int Getpassmark()
    {
        return this._passmark;
    }
}

يتم استخدام الخصائص لكشف الحقل.يستخدمون أدوات الوصول (set، get) التي يمكن من خلالها قراءة قيم الحقول الخاصة أو كتابتها أو معالجتها.

الخصائص لا تسمي مواقع التخزين.وبدلاً من ذلك، لديهم أدوات الوصول التي تقرأ أو تكتب أو تحسب قيمها.

باستخدام الخصائص، يمكننا ضبط التحقق من صحة نوع البيانات التي تم تعيينها في الحقل.

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

يمكننا القيام بذلك بطريقتين باستخدام getter وsetters واستخدام الخاصية.

 Using Getter and Setter

    // field
    private int _age;

    // setter
    public void set(int age){
      if (age <=0)
       throw new Exception();

      this._age = age;
    }

    // getter
    public int get (){
      return this._age;
    }

 Now using property we can do the same thing. In the value is a key word

    private int _age;

    public int Age{
    get{
        return this._age;
    }

    set{
       if (value <= 0)
         throw new Exception()
       }
    }

خاصية التنفيذ التلقائي إذا لم نقم بالمنطق في الحصول على أدوات الوصول وتعيينها، فيمكننا استخدام خاصية التنفيذ التلقائي.

عندما شتقوم مجموعات الخصائص التي يتم تنفيذها تلقائيًا بإنشاء حقل خاص ومجهول والتي لا يمكن الوصول إليها إلا من خلال الحصول على الوصول وتعيينه.

public int Age{get;set;}

خصائص مجردةقد تحتوي الفئة المجردة على خاصية مجردة، والتي يجب تنفيذها في الفئة المشتقة

public abstract class Person
   {
      public abstract string Name
      {
         get;
         set;
      }
      public abstract int Age
      {
         get;
         set;
      }
   }

// overriden something like this
// Declare a Name property of type string:
  public override string Name
  {
     get
     {
        return name;
     }
     set
     {
        name = value;
     }
  }

يمكننا تعيين عقار بشكل خاص في هذا يمكننا تعيين خاصية السيارات بشكل خاص (تم تعيينها في الفصل)

public int MyProperty
{
    get; private set;
}

يمكنك تحقيق نفس الشيء مع هذا الرمز.لا تتوفر ميزة مجموعة الخصائص هذه حيث يتعين علينا تعيين القيمة للحقل مباشرة.

private int myProperty;
public int MyProperty
{
    get { return myProperty; }
}

فكر في الأمر :لديك غرفة وباب لدخول هذه الغرفة.إذا كنت تريد التحقق من كيفية دخول الأشخاص وتأمين غرفتك، فيجب عليك استخدام العقارات وإلا فلن يكون هناك أي باب ويمكن دخول كل شخص بسهولة بدون أي تنظيم

class Room {
   public string sectionOne;
   public string sectionTwo;
}

Room r = new Room();
r.sectionOne = "enter";

يدخل الأشخاص إلى القسم الأول بسهولة تامة، ولم يكن هناك أي فحص

class Room 
{
   private string sectionOne;
   private string sectionTwo;

   public string SectionOne 
   {
      get 
      {
        return sectionOne; 
      }
      set 
      { 
        sectionOne = Check(value); 
      }
   }
}

Room r = new Room();
r.SectionOne = "enter";

الآن قمت بفحص الشخص ومعرفة ما إذا كان معه شيء شرير

في الغالبية العظمى من الحالات، سيكون اسم خاصية يمكنك الوصول إليه بدلاً من اسم متغير (مجال) والسبب في ذلك هو أنها تعتبر ممارسة جيدة في .NET وفي C# على وجه الخصوص لحماية كل جزء من البيانات داخل الفصل، سواء كان متغير مثيل أو متغير ثابت (متغير الفئة) لأنه مرتبط بفصل دراسي.

قم بحماية كل تلك المتغيرات بالخصائص المقابلة التي تسمح لك بتحديد، تعيين والحصول على الملحقات والقيام بأشياء مثل التحقق من الصحة عند التعامل مع تلك الأجزاء من البيانات.

ولكن في حالات أخرى مثل صف الرياضيات (مساحة اسم النظام)، هناك بعض الخصائص الثابتة المضمنة في الفصل.واحد منها هو ثابت الرياضيات باي

على سبيل المثال.الرياضيات.PI

ولأن PI عبارة عن جزء من البيانات محددة جيدًا، فإننا لا نحتاج إلى نسخ متعددة من PI، وستكون دائمًا نفس القيمة.لذلك تُستخدم المتغيرات الثابتة أحيانًا لمشاركة البيانات بين كائنات فئة ما، ولكنها تُستخدم أيضًا بشكل شائع للمعلومات الثابتة حيث تحتاج فقط إلى نسخة واحدة من جزء من البيانات.

الفرق الأساسي والعامة هو:

مجالات

  • دائماً منح كل من الحصول على حق الوصول وتعيينه
  • لا تستطيع تسبب آثارًا جانبية (طرح الاستثناءات، وطرق الاتصال، وتغيير الحقول باستثناء الحقل الذي تم الحصول عليه/تعيينه، وما إلى ذلك)

ملكيات

  • ليس دائما منح كل من الحصول على حق الوصول وتعيينه
  • يستطيع تسبب آثار جانبية
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top