سؤال

هل هناك أي طريقة للوصول إلى حقل الدعم لعقار من أجل القيام بالتحقق من الصحة ، وتغيير التتبع وما إلى ذلك؟

هل شيء مثل ما يلي ممكن؟ إذا لم يكن هناك أي خطط للحصول عليها في .NET 4 / C# 4؟

public string Name
{
    get;
    set
    {
        if (value != <Keyword>)
        {
            RaiseEvent();
        }
        <Keyword> = value;
    }
}

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

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

يحرر: لقد قمت بتغيير <حقل الدعم> إلى <wordword>. أود أن أقترح كلمة رئيسية جديدة مماثلة للقيمة. مجال هل سيفعل ذلك جيدًا على الرغم من أنني متأكد من أنه يتم استخدامه في الكثير من التعليمات البرمجية الموجودة.

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

المحلول

بعد قراءة تعليقاتك في إجابة Mehrdad ، أعتقد أنني أفهم مشكلتك بشكل أفضل قليلاً.

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

أود أن أقترح الاستراتيجية التالية. اكتب فئة عامة تمثل صحة. يحتفظ هذه الفئة فقط قيمة الدعم ولا يسمح إلا بالوصول/الطفرة عبر طرق GET and SET. يتم تمرير مندوب إلى ValuedValue لتمثيل منطق التحقق من الصحة:

public class ValidatedValue< T >
{
    private T m_val;
    public ValidationFn m_validationFn;

    public delegate bool ValidationFn( T fn );

    public ValidatedValue( ValidationFn validationFn )
    {
        m_validationFn = validationFn;
    }

    public T get()
    {
        return m_val;
    }

    public void set(T v)
    {
        if (m_validationFn(v))
        {
            m_val = v;
        }
    }
}

يمكنك ، بالطبع ، إضافة المزيد من المندوبين كما هو مطلوب (على سبيل المثال ، لدعم إشعار ما قبل التغيير/ما بعد).

سيستخدم الفصل الخاص بك الآن صحة Value بدلاً من متجر دعم للممتلكات الخاصة بك.

يوضح المثال أدناه فئة ، myClass ، مع عدد صحيح تم التحقق منه أقل من 100. لاحظ أن المنطق لرمي استثناء موجود في MyClass ، وليس صحة. يتيح لك ذلك القيام بقواعد التحقق من الصحة المعقدة التي تعتمد على حالة أخرى موجودة في MyClass. تم استخدام تدوين Lambda لبناء مندوب التحقق من الصحة - يمكن أن تكون ملزمًا بوظيفة عضو بدلاً من ذلك.

public partial class MyClass
{
    private ValidatedValue<int> m_foo;

    public MyClass()
    {
        m_foo = new ValidatedValue<int>(
            v => 
            {
                if (v >= 100) RaiseError();
                return true;
            }
        );
    }

    private void RaiseError()
    {
        // Put your logic here....
        throw new NotImplementedException();
    }

    public int Foo
    {
        get { return m_foo.get(); }
        set { m_foo.set(value); }
    }
}

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

نصائح أخرى

لا ليس هناك. إذا كنت ترغب في الوصول إلى حقل الدعم ، فلا تستخدم خصائص Auto وقم بتدحرجك.

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

كما MSDN تنص على:

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

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

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

لا ، لكن يمكنك في فئة فرعية:

public class Base
{
    public string Name
    {
        get;
        virtual set;
    }
}

public class Subclass : Base
{
    // FIXME Unsure as to the exact syntax.
    public string Name
    {
        override set
        {
            if (value != base.Name)
            {
                RaiseEvent();
            }

            base.Name = value;
        }
    }
}

إذا كنت ستفعل ذلك ، فلماذا تستخدم خصائص السيارات؟!

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

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top