لماذا لا يتم وضع علامة على خصائص مجموعة C# على أنها قديمة عند استدعاء الخصائص عليها؟

StackOverflow https://stackoverflow.com/questions/577132

  •  05-09-2019
  •  | 
  •  

سؤال

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


يحرر:لقد قمت بإرسال هذا من خلال Microsoft Connect، العدد رقم 417159.

تحرير 16.11.2010:تم التحقق من أن هذا يعمل الآن في برنامج التحويل البرمجي C# 4.0، سواء عند التحويل البرمجي لـ .NET 3.5 أو 4.0.حصلت على 4 تحذيرات في الكود المنشور، بما في ذلك التحذير الذي يحتوي على التعليق "ليس موافقًا؟".


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

إليك برنامج مثال، جاهز للتجميع في Visual Studio 2008.

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

هل هذا خطأ أم أن هذا "جوهرة مخفية" لمترجم C# الذي لم أكن على علم به؟

using System;
using System.Collections.Generic;

namespace TestApp
{
    public abstract class BaseClass
    {
        [Obsolete]
        public abstract String Value
        {
            get;
        }

        [Obsolete]
        public abstract String[] ValueArray
        {
            get;
        }

        [Obsolete]
        public abstract List<String> ValueList
        {
            get;
        }
    }

    public class DerivedClass : BaseClass
    {
        [Obsolete]
        public override String Value
        {
            get
            {
                return "Test";
            }
        }

        [Obsolete]
        public override String[] ValueArray
        {
            get
            {
                return new[] { "A", "B" };
            }
        }

        [Obsolete]
        public override List<String> ValueList
        {
            get
            {
                return new List<String>(new[] { "A", "B" });
            }
        }
    }

    public class Program
    {
        public static void Main(String[] args)
        {
            BaseClass bc = new DerivedClass();
            Console.Out.WriteLine(bc.Value);             // #1 - OK
            Console.Out.WriteLine(bc.ValueArray.Length); // #2 - OK
            Console.Out.WriteLine(bc.ValueList.Count);   // #3 - Not OK?
            List<String> list = bc.ValueList;            // #4 - OK
        }
    }
}
هل كانت مفيدة؟

المحلول

همم...يبدو وكأنه خطأ مترجم بالنسبة لي!فشل في ما يلي (ECMA 334v4):

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

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

(تحديث)

رمز مخفض لإعادة الإنتاج:

using System;
using System.Collections.Generic;
static class Program {
    static void Main() {
        int count = Test.Count;
    }

    [Obsolete("Should error", true)]
    public static List<string> Test {
        get {throw new NotImplementedException();}
    }
}

لاحظ أن mono 2.0 يقوم بذلك بشكل صحيح، كما يفعل برنامج التحويل البرمجي MS C# 2.0.إنه فقط برنامج التحويل البرمجي MS C# 3.0 (.NET 3.5) الذي تم تعطله.

نصائح أخرى

وهذا خطأ حقيقي.لسوء الحظ بسبب عملية إعادة البناء التي فاتتها هذه الحالة.لقد قمت بإصلاح هذا لإصدار برنامج التحويل البرمجي C# 4.0 القادم في VS 2010/NDP 4.0 ولكن لا توجد خطط لإصلاحه الآن في Orcas ولسوء الحظ لا يوجد عمل أعرفه للتعامل مع هذا.

أكره أن أقول ذلك ولكنك ستحتاج إلى الترقية إلى NDP 4 csc.exe أو VS2010 عندما يصبحان متاحين لإصلاح هذه المشكلة.

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

إيان هاليداي

مترجم C# SDE
مايكروسوفت

وأنا أتفق مع مارك:يبدو وكأنه خطأ مترجم.ومن المثير للاهتمام أن gmcs (المترجم Mono C#) يصحح الأمر:

Test.cs(65,26): warning CS0219: The variable `list' is assigned but its value is never used
Test.cs(62,38): warning CS0612: `TestApp.BaseClass.Value' is obsolete
Test.cs(63,38): warning CS0612: `TestApp.BaseClass.ValueArray' is obsolete
Test.cs(64,38): warning CS0612: `TestApp.BaseClass.ValueList' is obsolete
Test.cs(65,36): warning CS0612: `TestApp.BaseClass.ValueList' is obsolete
Compilation succeeded - 5 warning(s)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top