Microsoft-ui-xaml: الاقتراح: C # إسقاطات النقطة والمستقيم والحجم يجب ألا يتظاهر بالدقة المزدوجة

تم إنشاؤها على ١ مارس ٢٠٢٠  ·  59تعليقات  ·  مصدر: microsoft/microsoft-ui-xaml

في C # ، يبدو أن Point و Rect و Size لها دقة مزدوجة نظرًا لأن جميع خصائصها مزدوجة. لكن في الواقع ليس هذا هو الحال ، فهي في الواقع دقة واحدة. هذه ممارسة محيرة للغاية وسيئة للغاية في رأيي. في حالة رغبة أي شخص في التحقق من ذلك ، جرب الكود التالي.

ج #
مزدوج x = (مزدوج) تعويم. إبسيلون / 4.0 ؛
System.Diagnostics.Debug.WriteLine (x) ،
النقطة p = نقطة جديدة (x ، 0) ؛
System.Diagnostics.Debug.WriteLine (pX) ؛

It prints

3.50324616081204E-46
0
""
(لاحظ أنك قد تعتقد أن الرقم أعلاه صغير بشكل مثير للضحك ، ولكن من الناحية العملية عند العمل بمقاييس معقولة من حوالي 100-1000 بكسل للتخطيط ، تنخفض دقة العوامات إلى ما يشبه 0.0001 ، لا يمكنني أن أزعجني بذلك احسب قيم المثال في هذه الحالة).

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

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

area-DotNet bug team-Markup

التعليق الأكثر فائدة

dotMorten ، وآخرون - شكرًا على التعليقات. لقد قمنا بمراجعة التبديل من الخصائص المزدوجة إلى الخصائص العائمة في Rect و Point و Size. في حين أنه يجعل الإسقاط "صحيحًا" تقنيًا ، فإنه يخلق مقاومة كبيرة جدًا مع الخصائص والمتغيرات المزدوجة الأخرى ، ويؤدي إلى مشكلات توافق كبيرة. لذلك قررنا التراجع عن التغيير.

ال 59 كومينتر

في C # ، يبدو أن Point و Rect و Size لها دقة مزدوجة نظرًا لأن جميع خصائصها مزدوجة. لكن في الواقع ليس هذا هو الحال ، فهي في الواقع دقة واحدة. هذه ممارسة محيرة للغاية وسيئة للغاية في رأيي. في حالة رغبة أي شخص في التحقق من ذلك ، جرب الكود التالي.

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

أعتقد أن المشكلة تكمن في أنه عند استخدام نقطة في XAML ، لا يتم دعم / عمل تحديد عدد عشري (ويعرف أيضًا باسم Single).

من الوثائق :

إذا كنت تريد DP بنوع النقطة العائمة ، فاجعلها مزدوجة (Double in MIDL 3.0). إعلان وتنفيذ DP من نوع float (Single in MIDL) ، ثم تعيين قيمة لذلك DP في ترميز XAML ، ينتج عنه الخطأ فشل في إنشاء 'Windows.Foundation.Single' من النص ''.

لذا أعتقد أنه من أجل دعم استخدام النقاط في XAML ، قاموا بتعريفها على أنها مزدوجة في طبقة التجريد.

stevenbrix هل سيتم حل هذا من خلال عمل الإسقاط الجديد؟

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

هل سيتم حل هذا من خلال عمل الإسقاط الجديد؟

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

هذا مثير للاهتمام ، تقول الوثائق هنا أنه يجب أن يكون عائمًا: https://docs.microsoft.com/en-us/uwp/api/windows.foundation.point.x

كان الدافع وراء كون بوينت فرديًا هو الكمال. لقد بحثنا في مكان ما على طول الخط وكان الفردي في الغالب دقيقًا بدرجة كافية ، وتسبب المضاعف في حدوث نتيجة مثالية قابلة للقياس ، لذلك حاولنا عمومًا جعل الأشياء فردية داخليًا. في الوقت نفسه ، هناك دليل توجيهي لواجهة برمجة التطبيقات (في كل من .Net و Windows) لتفضيل المضاعفة ، لأن اللغات مثل ضعف أفضل من اللغة الفردية (على سبيل المثال var num = 0.0 في C # تجعل num a مزدوج)

نتيجة تلك الدوافع المتعارضة هي أنه بالنسبة إلى Silverlight و Xaml (WinUI) ، تكون بعض الأنواع مفردة داخليًا ولكن يتم عرضها في واجهة برمجة التطبيقات العامة على أنها مزدوجة. على سبيل المثال ، FrameworkElement.Width هو ضعف في واجهة برمجة التطبيقات ولكنه عائم داخليًا. من ناحية أخرى ، MapControl.ZoomLevel ، حيث الدقة مهمة حقًا ، إنها حقًا مزدوجة داخليًا.

عندما تم تصميم نوع Windows Point في الأصل ، تم تركه على أنه عائم ، ويمكنك رؤيته بهذه الطريقة في C ++. في C # ، على الرغم من ذلك ، لا يزال يمثل ضعف التوافق. هناك ملاحظة في صفحة مستند Point حول ذلك (ولكن ليس في صفحة مستند الحقل التي ربطها ستيفن بريكس).

(لمعلوماتك ، هناك أيضًا نوع PointInt32 يُستخدم في مكانين وهو Int32 من الأسفل إلى الأعلى.)

stevenbrix ، لقد ربطت مستندات UWP لإظهار "تعويم X". لكن مستندات dotnet مزدوجة الدقة. لذلك لا أعتقد أن هناك أي مشكلة ، بخلاف أن إظهار C # محير بعض الشيء ، لأن الإسقاط يخفي ذلك.

ينتقل الإسقاط الحالي لـ Point، Size، Rect إلى مساحة اسم Windows.Foundation ، بدلاً من استخدام نظام الدقة المزدوجة لأنواع Windows. بالنظر إلى ذلك ، أنا منفتح على إصلاح هذا من خلال الحفاظ على تعيين WF ولكن جعل الأنواع دقيقة واحدة. إنه تغيير جذري ، لكنه فرصة نادرة.

danzil ، وفقًا لملاحظةchingucoding ، هل يحتاج برنامج التحويل البرمجي / وقت التشغيل Xaml إلى التغيير لاستيعاب هياكل الدقة الفردية؟

إنه تغيير جذري ، لكنه فرصة نادرة.

سيكون ذلك رائعًا ، فالكثير من أخطاء الاقتطاع المحتملة ستختفي.

لكن المستندات لا تأخذك إلى هناك ، بل تأخذك إلى المستند الذي ربطه ستيفن بريكس. (على سبيل المثال ، ابدأ من PointAnimation واتبع الرابط

نحن نعمل بجد حتى لا نتعامل مع WinUI 3 كفرصة لإجراء تغييرات جذرية. هناك أشياء يتعين علينا كسرها لأسباب فنية أو متعلقة بالتوقيت ، لذلك تجنبنا أي ألم للتغيير يمكن تجنبه. (على سبيل المثال ، يصبح هذا خطأ في المترجم: point.X = 4.2; ) ألا يمكننا إجراء هذا التغيير في إصدار لاحق؟

نعم ، تعد مستندات UWP مربكة بعض الشيء كنقطة بداية ، نظرًا لعدم إدراكهم لسلوك الإسقاط C #.

بالنسبة لـ C # / WinRT ، كنا نمضي قدمًا على افتراض أنه سيتعين على المستخدمين إعادة البناء وربما إعادة الكتابة قليلاً (على سبيل المثال ، إسقاط مساعدي التشغيل المتداخل winrt). يبدو أن WinUI أكثر تحفظًا ، وهذا تحدٍ حيث يتقاطع الاثنان. أعتقد أن تغيير التغييرات سيكون أكثر صعوبة كلما طالت المدة ، حيث تتراكم مصادر معتمدة أكثر.

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

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

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

  • WinUI 3.0 - الحد الأدنى من التغييرات الفاصلة باستثناء مساحة الاسم من Windows -> Microsoft.
  • WinUI 3.1 - مخطط تغييرات أخرى (عدد محدود من)

هناك شيء واحد أعتقد أننا نتفق عليه وهو أن السلوك الحالي لـ Point وما إلى ذلك في C # محير! (أنا أفهم نوعًا ما الدافع الأصلي ، لكني لست متأكدًا من أنه كان القرار الأفضل ...).

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

أيضًا ، فيما يتعلق بالنقطة المتعلقة بضرورة تغيير برنامج التحويل البرمجي XAML ، لا أعرف الإجابة على ذلك ، لكنني قمت بنشر مشكلة لها في نفس الوقت الذي نشرت فيه هذه المشكلة ، في حالة ارتباطها - راجع # 2048.

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

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

التصميم الأصلي لاستخدام الاقتطاع المزدوج والصامت هو مجرد خطأ.

متفق عليه ، أعتقد أن هذه يجب أن تعرض فقط كيفية تنفيذها تحت الأغطية (مثل العوامات). إذا كان المترجم / وقت التشغيل بحاجة إلى إصلاح لقبول الطفو ، فهذا ما يجب أن نفعله في رأيي. FrameworkElement.Width الرغم من أن double ، فهل هذه واحدة من تلك الحالات التي تتصرف فيها أنواعنا الداخلية بشكل مختلف عن الأنواع الخارجية؟

بعد مناقشة ذات صلة ، تم طرح الاقتراح للحفاظ على موصّلات خاصية الدقة المزدوجة ، على سبيل المثال Point.X ، وإضافة فحص الحدود (على سبيل المثال ، رمي إذا كان المضاعف أكبر من عدد عشري) ، ولكن أيضًا إضافة وصول مباشر وفعال إلى مفرد مخازن دعم الدقة. سيكون الهيكل المتوقع ضعيفًا ، لذا فإن عبور ABI سيكون رخيصًا.

وبالتالي،
نقطة pt
pt.X = GetDouble () ،
pt.x = GetFloat () ،

خواطر؟

أعتقد أن هذا قد يؤدي إلى حدوث مشاكل في تعيين القيمة إلى ضعف عرضي وأن التطبيقات تبدأ الآن في التعامل مع هذا الاستثناء.

من ناحية أخرى ، سيؤدي ذلك بالتأكيد إلى زيادة الوعي بالموقف وسيعرف الناس بالتأكيد متى تكون القيم غير دقيقة.

رمي إذا كان المضاعف أكبر من العوامة

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

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

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

بخلاف ذلك ، يبدو ذلك معقولًا ، على الرغم من أنني لست متأكدًا بنسبة 100٪ من الأحرف الصغيرة x لاسم الخاصية. يبدو أن الأحرف الصغيرة تتعارض مع اصطلاحات التسمية الحالية لـ C # و UWP.

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

تضمين التغريدة

بعد مناقشة ذات صلة ، تم طرح الاقتراح للحفاظ على موصّلات خاصية الدقة المزدوجة ، على سبيل المثال Point.X ، وإضافة فحص الحدود (على سبيل المثال ، رمي إذا كان المضاعف أكبر من عدد عشري) ، ولكن أيضًا إضافة وصول مباشر وفعال إلى مفرد مخازن دعم الدقة. سيكون الهيكل المتوقع ضعيفًا ، لذا فإن عبور ABI سيكون رخيصًا.

وبالتالي،
نقطة pt
pt.X = GetDouble () ،
pt.x = GetFloat () ،

خواطر؟

أعتقد أن هذا سيسبب مزيدًا من الارتباك على المدى الطويل. ما أعنيه هو - يتوقع الناس استخدام UpperCamelCase ، لذا فإن 99.9٪ سوف يستخدم X بغض النظر عن ذلك.

وجهة نظري (يقصد التورية) هي أن هذه فئة يجب أن يكون استخدامها تافهًا تمامًا. إنها نقطة ذات إحداثيين - X ، Y - هذا كل شيء. لماذا تجعلها معقدة؟

تقديم الإسقاط "المزدوج" خطأ كبير IMHO:

  1. التعامل مع اللانهاية (المضاعفة) لن ينجح
  2. بسبب التقريب الدقيق ، أعتقد أنه يمكنك التعامل مع قضايا مثل هذه
    Point p;
    p.X = some_crazy_double_value;
    if ( p.X == some_crazy_double_value) 
        // will never execute
        do_stuff();

أنا أقدر ردود الفعل على هذا.

لدينا خيار الحفاظ على توافق المصدر (الذي لا أعتقد أن أي شخص يدافع عنه) ، مع:

struct Point
{
    float _x;
    float _y;

    public Point(double x, double y)
    {
        _x = (float)x;
        _y = (float)y;
    }

    public double X { get => _x; set =>_x = (float)value; }
    public double Y { get => _y; set =>_y = (float)value; }
}

أو تحقق من صحة الحقول ، ربما بشيء مثل هذا:

struct Point
{
    public Point(float x, float y)
    {
        _x = x; 
        _y = y;
    }

    public Point(double x, double y)
    {
        _x = (float)x; 
        _y = (float)y;
        Validate(_x, x);
        Validate(_y, y);
    }

    public float _x;
    public double X { get => _x; set { _x = (float)value; Validate(_x, value); } }

    public float _y;
    public double Y { get => _y; set { _y = (float)value; Validate(_y, value); } }

    [Conditional("DEBUG")]  // or "WINRT_VALIDATE"
    void Validate(float field, double value, [CallerMemberName] string member = "")
    {
        if ((double)field != value && !float.IsNaN(field))
        {
            throw new ArgumentOutOfRangeException(member);
        }
    }
};

الإصدار الثاني عبارة عن مجموعة شاملة من بنية النقاط الحالية.

اي اهتمامات؟

اي اهتمامات؟

هذا يلقي دائما تقريبا؟ Mantissa أوسع للمضاعفة لذا يكاد يكون مضمونًا أن تفقد المعلومات عند الإرسال.

نعم ، كنت سأقول بالتأكيد new Point(1.0/3.0, 1.0/3.0) أو أي شيء مشابه سيرمي. هل تعني السمة [الشرطية ("DEBUG")] أن استدعاء الأسلوب لا يفعل شيئًا إذا كان مدمجًا في وضع الإصدار؟

لا تحتاج إلى أي حسابات ، لقد فشلت بالفعل في الثوابت البسيطة. حتى شيء بسيط مثل 0.7 أو 0.3 قد يرمي لأن الجزء العشري ثنائي ولا يمكن تمثيل أي من الثابتين بالضبط. لا تنتقل معظم الكسور العشرية بشكل واضح إلى نظام ثنائي لأن الكسر العشري يحتوي على قاسم أولي 5 و 2 بينما يحتوي النظام الثنائي على 2 فقط.

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

نقاط جيدة ، الكل - كان يجب أن أختبرها ببعض الكسور العشرية البسيطة.

weltkante ، أين يمكنك تطبيق السمة القديمة؟ بالتأكيد إلى النقطة (مزدوج ، مزدوج) أمر منطقي ، حيث يوجه المستخدمين إلى Point (تعويم ، تعويم). لكن موصلي خاصية X و Y أنفسهم ، إذا ما تم تقادمهم ، لن يتركوا مجالًا لتعيين الممتلكات بأمان بواسطة الطفو.

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

أين يمكنك تطبيق السمة القديمة؟

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

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

أنا شخصياً سعيد بتغيير النوع ، لكنني أدرك أيضًا أنه قد يكون تغييرًا كبيرًا جدًا.

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

إذا كنت تشعر أن الحفاظ على توافق المصدر مطلوب ، فأنا أفضل شيئًا كهذا.
ج #
هيكل نقطة
{
نقطة عامة (عائم س ، عائم ص)
{
_x = س ؛
_y = ص ؛
}

public Point(double x, double y)
{
    _x = (float)x; 
    _y = (float)y;
}

float _x;
public float XValue { get => _x; set { _x = value;} }
public double X { get => _x; set { _x = (float)value; } }

float _y;
public float YValue { get => _y; set { _y = value;} }
public double Y { get => _y; set { _y = (float)value; } }

}
`` Possibly you could special case some values like infinity, but I'd have to read up a bit more on the technical specifications of float and double to say more. Having written this, it does feel rather horrible to have to use XValue and YValue` ...

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

أحد الأمثلة على ذلك هو خطوات الترتيب / التجاوز

هل يمكنك مشاركة الكود الذي لديك؟ هذه هي الأمثلة المثالية التي نحتاجها لاتخاذ القرارات الصحيحة.

stevenbrix ، هذا مثال بسيط واحد فقط ، ولكن سرعان ما يحصل على المزيد والمزيد منه. يتم تجميع الكود لـ UWP وليس لـ Win32:

        protected override Size ArrangeOverride(Size finalSize)
        {
            int count = Children.Count;
            var width = (finalSize.Width - (count + 1) * (CellMargin.Left - CellMargin.Right)) / finalSize.Width;
            var x = CellMargin.Left;
            foreach(var child in Children)
            {
                child.Arrange(new Rect(x, 0, width, finalSize.Height));
                x += CellMargin.Right + CellMargin.Left;
            }
            return base.ArrangeOverride(finalSize);
        }

        public Thickness CellMargin
        {
            get { return (Thickness)GetValue(CellMarginProperty); }
            set { SetValue(CellMarginProperty, value); }
        }

        public static readonly DependencyProperty CellMarginProperty =
            DependencyProperty.Register("CellMargin", typeof(Thickness), typeof(MyCustomControl), new PropertyMetadata(new Thickness()));

الإصلاح هو أن يطفو فقط لـ Win32 ، وهو أمر قبيح. من المؤكد أنك قد تقوم بإصلاح عدم الاتساق في UWP بحيث يتم تعويمها جميعًا ولا يتعين علينا #if-def ، ولكن من الغريب أن جميع خصائص التخطيط لا تتطابق في نوع البيانات.

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

... أيضًا بالنسبة لأولئك منا الذين يعيدون استخدام الكود مع WPF و UWP "القديم" ، فهو أكثر اضطرابًا

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

  • هل تتوقع دائمًا أن يتضاعف مشروع تعويم C #؟
  • أو فقط في واجهات برمجة تطبيقات WinUI المحددة؟
  • أو في WinUI كمكتبة؟
  • أو أيضًا في مكتبات C ++ التي يحددها المستخدم؟
  • أو فقط في WinUI + المستخدم في عناصر تحكم C ++ UI؟

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

وماذا عن الخصائص الأخرى التي تطفو "حقًا" مثل ActualWidth / Height إلخ؟ يجب أن يكون كل شيء أو لا شيء ، أو IMHO الحجة لهذا التغيير تنهار. لكن إذا فعلت كل شيء ، يمكننا حقًا البدء في الحديث عن تغيير مزعزع.
لا أستفيد حقًا من التغيير إلى الطفو. يبدو أكاديميًا أكثر منه حول شيء نحتاجه بالفعل.

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

(لست هنا لمناقشة أو التصويت لأي من الجانبين ، أردت فقط طرح مسألة النطاق لأن هذا قد لا يكون بالضرورة متعلقًا بـ WinUI فقط ، مع إعادة تنفيذ الإسقاط.)

weltkante لقد
كما أن هذا التغيير لا يفسر سبب عدم تغيير جميع العوامات المزدوجة أيضًا

تم بالفعل تعويم UWP 10240 لأعضاء Point في API. فقط C # رآها مضاعفة بقدر ما أفهمها. ربما أسيء فهم الأشياء ، وأنا لا أستبعد ذلك.

لذلك ليس تغييرًا في WinUI API ، إنه تغيير في الإسقاط ، وإذا كان الوهم المزدوج سيستمر هناك ، فإن السؤال هو في أي نطاق.

لذلك ليس تغييرًا في WinUI API ، إنه تغيير في الإسقاط ،

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

لذا فإن هذه القضية تتعلق تحديدًا بالإسقاط. ولا يحتوي إسقاط المعاينة لـ NET5 على التحويل المزدوج.

dotMorten أوافق على أنه سيكون من المنطقي على الأرجح تغيير جميع الزوجي - التي - هي - بالفعل - تعويم إذا حدث هذا على الإطلاق. هل يتم النظر في ذلك؟ في عالم مثالي ، أعتقد أن أفضل حل هو أن كل الزوجي - الذي هو حقًا - يطفو في الواقع سيكون زوجيًا - هذا - حقًا - زوجي ، لكن هذا لن يحدث بقدر ما أستطيع رؤيته. لم أعد أعرف ما هو الحل الأفضل. أعتقد أنه ربما يكون من الواضح جدًا في المستندات و intellisense أن الخصائص هي في الواقع ذات دقة واحدة فقط على الرغم من أنها مزدوجة هي أفضل طريقة للمضي قدمًا ، إلى جانب ربما الوصول المباشر إلى العوامات كما هو موضح في https: // github .com / microsoft / microsoft-ui-xaml / issues / 2047 # issuecomment -605512398. من المهم أن تعرف على الأقل أن هذه الخصائص هي حقًا دقة فردية عند القيام بأشياء مثل تنسيق الحسابات الهندسية التي تتطلب تفاوتًا للخطأ.

لم أعد أعرف ما هو الحل الأفضل

نفس الشيئ :)

لا أعتقد أن نقل كل نوع WinUI إلى float ممكن. سيكون تغييرًا كبيرًا جدًا من شأنه أن يجعل الهجرة أكثر صعوبة.

أعتقد أنه من المهم للغاية الحفاظ على توافق المصدر ، والألم الذي يسببه هذا للأشخاص الذين يرغبون في التفاعل مع WPF / UWP لا يستحق التغيير.

يعجبني الاقتراح الوارد في هذا التعليق أيضًا ، على الرغم من أنني لست معجبًا بخصائص XValue و YValue . يمكننا توفير المُنشئين كما اقترح سكوت ، ولدينا محلل Roslyn يكتشف استخدام المُنشئ الذي يأخذ double ويوفر مصباحًا صغيرًا يقول إن هذا يمكن أن ينقطع. أو حتى أبسط ، فقط لديك تعليقات xml التي من شأنها أن توفر نص تعليمات Intellisense

struct Point
{
    public Point(float x, float y)
    {
        _x = x; 
        _y = y;
    }

   /// <summary>
   /// Warning: The values for X and Y could be truncated if you require greater precision due to the backing storage being float.
   /// </summary>
    public Point(double x, double y)
    {
        _x = (float)x; 
        _y = (float)y;
    }

    float _x;
    public double X { get => _x; set { _x = (float)value; } }

    float _y;
    public double Y { get => _y; set { _y = (float)value; } }

}

أنا ممزق نوعًا ما الآن بعد أن أدركت أن نوع WinRT عائم. إنه أمر قبيح أن أتعامل معه ولكني الآن أحصل عليه الآن.

إذا احتفظت بالإعدادات الافتراضية لكل من Win32 و UWP - فهل هناك طريقة لتمكين المطورين من تجاوز المضاعفة واستخدام عدد عشري؟

هذه مكالمة صعبة ، وهذا هو سبب قيامنا بالمعاينة مع التبديل من الوضع المزدوج إلى التعويم ، حتى نتمكن من جمع تعليقات المجتمع. فيما يتعلق بالتحويل الشامل من المضاعفة إلى الطفو ، فهي مشكلة فقط بالنسبة للهياكل الهندسية الثلاثة. كانت هذه مخصصة تحويلات تعيين نوع WinRT / .NET . لاحظ أنه لا توجد تعيينات أخرى لنوع القيمة المخصصة في الرابط أعلاه تحتوي على حقول قائمة على عدد عشري - فهي كلها مزدوجة أو متكاملة. يتضمن ذلك جميع أنواع Windows.UI.Xaml * (مثل السماكة) وأنواع النظام مثل TimeSpan. لذا فإن عدم تطابق المعاوقة الذي نحتاج إلى معالجته هو فقط لهذه الأنواع الثلاثة.

mdtauk ، نعم ، يمكننا بالتأكيد توفير تجميع شرطي للتبديل بين مزدوج وتعويم عند

لقد نثرت رؤوس الكود الخاص بي بهذا:

#if WINUI && NETCOREAPP
using uiunits = System.Single; 
#else
using uiunits = System.Double;
#endif

ثم استخدم var بدلاً من double للاعتماد على الأنواع الضمنية وإلقاء الضوء عمومًا على النحو التالي:
new Point((uiunits)x, (uiunits)y);

أدى ذلك إلى جعل التغييرات في الكود أكثر احتمالًا ، ولكن كان لا يزال يتعين علي لمس 100 ملف.

(لاحظ أن معظم هذه التعليمات البرمجية يتم تجميعها لـ WPF و UWP و WinUI)

إليك فكرة بديلة: قدم Microsoft.UI.Point / Rect / Size واستخدمها لجميع عناصر تخطيط واجهة المستخدم بدلاً من ذلك ، واجعل هذه الدقة المزدوجة ، لذلك ليس لدينا للقيام بكل هذا الإرسال ذهابًا وإيابًا ، وتوقف عن استخدام Windows.Foundation.Point / Rect / Size . يبدو أنه من الغريب استخدام أنواع النوافذ هذه في جميع عناصر التخطيط على أي حال.

لاحظ أنه لا توجد تعيينات أخرى لنوع القيمة المخصصة في الرابط أعلاه تحتوي على حقول قائمة على عدد عشري - فهي كلها مزدوجة أو متكاملة.

@ Scottj1s - قد يكون هذا صحيحًا من حيث الأنواع ، ولكنه صحيح بالنسبة لجميع الخصائص التي يتم عرضها على شكل أزواج ، على سبيل المثال ، ActualHeight ، ActualWidth؟ لم أختبرها ، لكن بالنظر إلى أن الخاصية ActualSize الجديدة هي نقطة عائمة ، أجد صعوبة في تصديق أن ActualWidth و ActualHeight هما حقًا ضعفين. أفترض أن هذا لا يهم كثيرًا نظرًا لأنه لا يمكنك بالفعل تعيين هذه ، ولكن سيكون من الجيد أن تكون متسقًا.

@ benstevens48 - كنت أشير فقط إلى ألم التحويل لإصلاح ما تم توقعه سابقًا (بشكل غير صحيح) كمضاعفات - أنواع الهندسة. قد يتم تخزين ActualHeight و ActualWidth داخليًا على هيئة عوامات ، نظرًا لأن ActualSize هو ناقل 2 ، كما أشرت. ولكن هذه تفاصيل تنفيذ UIElement / FrameworkElement. تم بالفعل إسقاط هذه الخصائص بأمانة على أنها مزدوجة.
dotMorten - أعتقد أن هذا قد يكون تغييرًا جذريًا أكبر. هل ترغب في سماع رأي فريق WinUI في هذا الاقتراح.

🦙 الربط المتقاطع مع الريبو CS / WinRT الجديد.

dotMorten ، وآخرون - شكرًا على التعليقات. لقد قمنا بمراجعة التبديل من الخصائص المزدوجة إلى الخصائص العائمة في Rect و Point و Size. في حين أنه يجعل الإسقاط "صحيحًا" تقنيًا ، فإنه يخلق مقاومة كبيرة جدًا مع الخصائص والمتغيرات المزدوجة الأخرى ، ويؤدي إلى مشكلات توافق كبيرة. لذلك قررنا التراجع عن التغيير.

@ Scottj1s - هل تخطط لفضح الوصول المباشر إلى خصائص الطفو (عبر أسماء متغيرات بديلة) ، وربما مُنشئ تعويم ، كما تمت مناقشته سابقًا في هذا الموضوع؟

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

@ Scottj1s - هل يمكنك التفكير في عرض حقول الدعم عبر خاصية getter / setter التي تتوافق مع اصطلاحات تسمية C #؟

@ benstevens48 ما الذي تحاول تحقيقه بالضبط؟ هل هذا للاستخدام مع WinUI ، أم أنك تحاول استخدام هذه الأنواع خارج WinUI؟

@ benstevens48 - هل يمكنك تقديم مثال محدد ، على سبيل المثال لـ Point؟ هل هذا لأغراض ملزمة؟

في الواقع ، ربما يكون من الأفضل كشف الخصائص المزدوجة فقط.

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

كانت حالة الاستخدام الأصلية الرئيسية الخاصة بي خارج WinUI تتعلق بنقطة / متجه 2 ذات دقة مزدوجة (نظرًا لعدم توفرها حتى الآن .net) ، ولكن من الواضح أن هذا غير ممكن بالفعل ، على الرغم من أنه من المغري جدًا استخدام Point لهذا الغرض ، نداء للحصول على مستندات واضحة.

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

نظرًا لأن شاشات العرض تكبر ، فهل من المنطقي بدلاً من ذلك جعل حقول الدعم double دقة حيث يقول سطح API بالفعل أنها كذلك؟ أم أنه سيكون هناك العديد من التداعيات لتغيير ذلك؟

يعد تغيير حقول الدعم تغييرًا في ABI ، مع تموجات أكبر ومشكلات التوافق ، مما يؤثر على اللغات الأخرى وعمليات تنفيذ المكونات التي تستخدم هذه الأنواع. تغيير كل شيء آخر (المنشئات ، أدوات الوصول إلى الممتلكات ، الطرق ، إلخ) يؤثر فقط على كود العميل C #.

كانت حالة الاستخدام الأصلية الرئيسية الخاصة بي خارج WinUI تتعلق بنقطة / متجه مزدوج الدقة

هناك طرق تمديد لذلك:

image

jtorjo - أعني أنني أردت طريقة لتخزين زوج من قيم الدقة المزدوجة. من الواضح أن استخدام Point كان خاطئًا ، لكن الأمر استغرق بعض الوقت ليدركه الرجل. يحتوي .Net على Vector2 بدقة مفردة حاليًا (على الرغم من وجود اقتراح مزدوج على ما أعتقد).

هذا أحد أخطاء التصميم التي تبين أنها مؤلمة جدًا لاحقًا - بسبب الاحتكاك الذي يسببه للمطورين في كلتا الحالتين. إن ترك الأمر كما هو واختيار إصلاحه يمثلان تحديات. في مرحلة ما ، قد يتم النظر في تغيير البيانات الوصفية لـ WinUI (كما تم اقتراحه). يمكن بعد ذلك الاشتراك في واجهات / طرق جديدة. في غضون ذلك ، شعرنا أنه من الأفضل الحفاظ على السلوك القديم في طبقة الإسقاط (التي توفرها الآن C # / WinRT) لتجنب المفاجآت والتناقضات.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات