سؤال

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

هل هناك أداة أو علامة مترجم حتى أتمكن من عرض ما ينشئ المحول البرمجي من تعبير الاستعلام، لذا فأنا أركذه؟

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

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

المحلول

رمز فهم الاستعلام الخاص بك هو:

from f1 in e1
from f2 in e2
from f3 in e3
select f3

رمز الاتصال الأسلوب الخاص بك هو:

e1
.SelectMany(f1 => e2)
.SelectMany(f2 => e3), (f2, f3) => f3))

عائدات الترجمة الاستعلام على النحو التالي. أولا نحن نتعامل مع أول اثنين من البنود:

from f1 in e1
from f2 in e2
from f3 in e3
select f3;

يتم ترجم هذا إلى

from x in ( e1 ) . SelectMany( f1 => e2 , ( f1 , f2 ) => new { f1 , f2 } )
from f3 in e3
select f3;

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

ثم يتم تحويل هذه النتيجة إلى

( ( e1 ) . SelectMany( f1 => e2 , ( f1 , f2 ) => new { f1 , f2 } ) ) 
.SelectMany( x => e3 , ( x , f3 ) => f3 )

يمكننا القضاء على بعض القيوeces:

e1 
.SelectMany( f1 => e2 , ( f1 , f2 ) => new { f1 , f2 } ) ) 
.SelectMany( x => e3 , ( x , f3 ) => f3 )

من الواضح أن هذا مختلف تماما عن التحول النحوي الذي قمت به يدويا، والذي أذكر، كان

e1
.SelectMany(f1 => e2)
.SelectMany(f2 => e3), (f2, f3) => f3))

إذا بديلا في E1 الخاص بك، E2، E3 في التحول النحوي الفعلي أعلاه، هل يستنتج نوع التعبير الناتج؟

إذا لم يفعل ذلك، فإن السؤال هو "لماذا لا؟" إما أن هناك شيئا خاطئا في التعليمات البرمجية الخاصة بك، أو خطأ ما في Inferrer النوع. إذا كان هناك خطأ ما في Inferrer النوع، فأعلمني بذلك.

إذا فعل ذلك، فإن السؤال هو "ما هو الخطأ في تمريرة التحول النحوية"؟ إذا كان هناك شيء خاطئ في تمريرة تحويل النحوية، مرة أخرى، اسمحوا لي أن أعرف.

شكرًا!

نصائح أخرى

يمكنك استخدام العاكس وعرض التعليمات البرمجية الخاصة بك مع إيقاف تشغيل الأمثل.

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

from x in Foo.Bar()
...

كان من المفترض أن يعيد Foo.Bar () إرجاع مستقبل و X كان من المفترض أن يكون من النوع المستقبلي من النوع، لكن هذا لا يعمل مع ترجمة الاستعلام. لقد تناولت ذلك عن طريق إضافة طبقة أخرى من غير مباشر، في الأساس عن الطرق الآجلة في القول، Asyncu003CT> اكتب، والتي لا يمكن إرساءها إلا مع العقود المستقبلية، أي.

public sealed class Async<T> { internal T value; }
public static class Async
{
   public static Async<Future<T>> Begin<T>(Future<T> future) { ... }
}

ثم يمكنني كتابة حساب الاستعلام على قيم ASYNC، لذلك يصبح التعبير شيئا مثل:

from x in Async.Begin(Foo.Bar())
...

حيث X هو الآن من نوع المستقبل، يمكنني إجبار أو تأجيل العقود المستقبلية والوعود بشكل تعسفي.

شكرا على الاقتراحات الجميع. سيكون مترجم التعبير الاستعلام المدمج في Visual Studio جميلا رغم ذلك، في حالة قراءة أي شخص في MS هذا. ؛-)

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