مشاركة عبر


الإرشادات التفصيلية: إنشاء ثم استخدام الكائنات الديناميكية(C# و Visual Basic)

الكائنات الديناميكية تعرض الأعضاء مثل الخصائص والأساليب وقت التشغيل بدلاً من وقت يحول برمجياً. يتيح لك ذلكإنشاء كائنات للعمل مع بنيات التي لا تطابق نوع ثابت أو تنسيق. على سبيل المثال، يمكنك إستخدام الكائن الديناميكي لتشير إل ىمستند طراز كائن HTML (DOM) ، والتي يمكن أن تتضمن أي تركيبة صالحة عناصر علامات HTML وسماته. لأن كل مستند HTML يعد فريد , و يتم تحديد الأعضاء مستند HTML معين في وقت التشغيل. أسلوب شائع سمة عنصر HTML للرجوع إلى تمرير اسم السمة إلى أسلوب العنصر GetProperty . للرجوع إلى خاصية id للعنصر HTML <div id="Div1"> ، أولاً عليك الحصول على مرجع العنصر <div> ، ومن ثم إستخدم divElement.GetProperty("id"). إذا كنت تستخدم كائن حيوي يمكنك الرجوع إلى سمةid كـ divElement.id.

الإشارة إلى كائن حيوي بإستخدام ربط في وقت التشغيل. في C# ، تحدد نوع كائن منضم المتأخر كـ dynamic. في Visual Basic ،تقوم بتحديد نوع كائن منضم المتأخر كـ Object. للمزيد من المعلومات، راجع الحيوي (C# مرجع) وربط مبكر و المتأخر.

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

في هذه الإرشادات التفصيلية, سوف تؤدى المهام التالية:

  • إنشاء كائن مخصص كشف بشكل حيوي المحتويات ملف نصي كخصائص الكائن.

إنشاء كائن حيوي مخصص

المشروع الأول الذي تقوم بإنشائه في هذه معاينة يعرف الكائن الحيوي المخصص الذي يبحث في محتويات ملف نصي. نص للبحث المحدد بواسطة اسم خاصية حيوية. على سبيل المثال، في حالة استدعاء التعليمات البرمجية يحدد dynamicFile.Sample ، ترجع الفئة الحيوية قائمة سلاسل عامة تحتوي على كافة الأسطر من الملف التي تبدأ صواب "نموذج". البحث متحسس لحالة الأحرف. الفئة الديناميكية تدعم الوسيطتين اختيارية. الوسيطة الأولى هي خيار البحث تعداد المعرفة التي تحدد أن الفئة الديناميكية يجب أن تبحث عن تطابقات عند بداية السطر لنهاية السطر أو أي مكان في السطر. الوسيطة الثانية تقوم بتحديد يجب تشذيب فئة ديناميكي البادئة والزائدة المسافات من كل خط قبل البحث. على سبيل المثال، في حالة استدعاء التعليمات البرمجية يحدد dynamicFile.Sample(StringSearchOption.Contains) ، تقوم الفئة الديناميكية الحيوية بالبحث عن "نموذج" من أي مكان في السطر. في حالة استدعاء التعليمات البرمجية بتعيين dynamicFile.Sample(StringSearchOption.StartsWith, false) ، تبحث الفئة الديناميكية عن "نموذج" في بداية كل سطر و لا تزيل المسافات البادئة والزائدة. السلوك الافتراضي للفئة الديناميكية هو البحث عن تطابق في بداية كل خط لإزالة المسافات البادئة والزائدة.

إنشاء الفئة الديناميكية المخصصة.

  1. ابدأ Visual Studio.

  2. من القائمة File (ملف)، أشر إلى New (جديد)، ثم انقر فوق Project (مشروع).

  3. في مربع حوارمشروع جديد في قائمة أنواع المشروع تأكد من أن Windows محدد. اختر Console Application في لوحة Templates. في المربع فتح، اكتب Explorer، ثم انقر فوق موافق. يتم إنشاء مشروع جديد.

  4. انقر فوق المشروع نقرة الى اليمين DynamicSample ثم أشر إلى إضافةثم انقر فوق فئة. في المربع اسم، اكتب ReadOnlyFile، ثم انقر فوق موافق. تمت الإضافة ملف جديد يحتوي على الفئة ReadOnlyFile.

  5. في أعلى الملف ReadOnlyFile.cs أو ReadOnlyFile.vb أضف التعليمة البرمجية التالية لاستيراد System.IO و مساحات الأسماء System.Dynamic .

    Imports System.IO
    Imports System.Dynamic
    
    using System.IO;
    using System.Dynamic;
    
  6. الكائنات المخصصة الديناميكية تستخدم تعداد المعرفة لتحديد خصائص البحث. إضافة تعريف التعداد المعرفة التالية قبل عبارة الفئة.

    Public Enum StringSearchOption
        StartsWith
        Contains
        EndsWith
    End Enum
    
    public enum StringSearchOption
    {
        StartsWith,
        Contains,
        EndsWith
    }
    
  7. بتحديث بيان فئة الكشف ترث الفئة DynamicObject كما هو موضح في مثال التعليمات البرمجية التالية.

    Public Class ReadOnlyFile
        Inherits DynamicObject
    
    class ReadOnlyFile : DynamicObject
    
  8. أضف التعليمة البرمجية التالية إلى فئة ReadOnlyFile لتعريف الحقل الخاص لمسار الملف ومنشئ الفئة ReadOnlyFile .

    ' Store the path to the file and the initial line count value.
    Private p_filePath As String
    
    ' Public constructor. Verify that file exists and store the path in 
    ' the private variable.
    Public Sub New(ByVal filePath As String)
        If Not File.Exists(filePath) Then
            Throw New Exception("File path does not exist.")
        End If
    
        p_filePath = filePath
    End Sub
    
    // Store the path to the file and the initial line count value.
    private string p_filePath;
    
    // Public constructor. Verify that file exists and store the path in 
    // the private variable.
    public ReadOnlyFile(string filePath)
    {
        if (!File.Exists(filePath))
        {
            throw new Exception("File path does not exist.");
        }
    
        p_filePath = filePath;
    }
    
  9. قم بإضافة الأسلوب التالي GetPropertyValue إلى الفئة ReadOnlyFile . يأخذ أسلوب GetPropertyValue كإدخال , معايير البحث و إرجاع الأسطر من ملفات النص التي تطابق معايير البحث . أساليب الحيوية التي توفرها الفئة ReadOnlyFile تستدعي أسلوب GetPropertyValue لاسترداد النتائج الخاصة بهم.

    Public Function GetPropertyValue(ByVal propertyName As String,
                                     Optional ByVal StringSearchOption As StringSearchOption = StringSearchOption.StartsWith,
                                     Optional ByVal trimSpaces As Boolean = True) As List(Of String)
    
        Dim sr As StreamReader = Nothing
        Dim results As New List(Of String)
        Dim line = ""
        Dim testLine = ""
    
        Try
            sr = New StreamReader(p_filePath)
    
            While Not sr.EndOfStream
                line = sr.ReadLine()
    
                ' Perform a case-insensitive search by using the specified search options.
                testLine = UCase(line)
                If trimSpaces Then testLine = Trim(testLine)
    
                Select Case StringSearchOption
                    Case StringSearchOption.StartsWith
                        If testLine.StartsWith(UCase(propertyName)) Then results.Add(line)
                    Case StringSearchOption.Contains
                        If testLine.Contains(UCase(propertyName)) Then results.Add(line)
                    Case StringSearchOption.EndsWith
                        If testLine.EndsWith(UCase(propertyName)) Then results.Add(line)
                End Select
            End While
        Catch
            ' Trap any exception that occurs in reading the file and return Nothing.
            results = Nothing
        Finally
            If sr IsNot Nothing Then sr.Close()
        End Try
    
        Return results
    End Function
    
    public List<string> GetPropertyValue(string propertyName,
                                         StringSearchOption StringSearchOption = StringSearchOption.StartsWith,
                                         bool trimSpaces = true) 
    {
        StreamReader sr = null;
        List<string> results = new List<string>();
        string line = "";
        string testLine = "";
    
        try
        {
            sr = new StreamReader(p_filePath);
    
            while (!sr.EndOfStream)
            {
                line = sr.ReadLine();
    
                // Perform a case-insensitive search by using the specified search options.
                testLine = line.ToUpper();
                if (trimSpaces) { testLine = testLine.Trim(); }
    
                switch (StringSearchOption)
                {
                    case StringSearchOption.StartsWith:
                        if (testLine.StartsWith(propertyName.ToUpper())) { results.Add(line); }
                        break;
                    case StringSearchOption.Contains:
                        if (testLine.Contains(propertyName.ToUpper())) { results.Add(line); }
                        break;
                    case StringSearchOption.EndsWith:
                        if (testLine.EndsWith(propertyName.ToUpper())) { results.Add(line); }
                        break;
                }
            }
        }
        catch
        {
            // Trap any exception that occurs in reading the file and return null.
            results = null;
        }
        finally
        {
            if (sr != null) {sr.Close();}
        }
    
        return results;
    }
    
  10. بعد أسلوبGetPropertyValue قم بإضافة التعليمة البرمجية التالية لتجاوز أسلوب TryGetMember فئة DynamicObject. استدعاء الأسلوبTryGetMember عندما يطلب عضو من فئة حيوية و لا يكون هناك وسائط محددة. وسيطة binder تحتوي على معلومات عن العضو المشار اليه ، و تشير الوسيطةresult إلى نتيجة إرجاع العضو المحدد. يقوم الأسلوب TryGetMember بإرجاع قيمة boolean التي ترجع true في حالة وجود العضو المطلوب; وإلا تقوم بإرجاع false.

    ' Implement the TryGetMember method of the DynamicObject class for dynamic member calls.
    Public Overrides Function TryGetMember(ByVal binder As GetMemberBinder,
                                           ByRef result As Object) As Boolean
        result = GetPropertyValue(binder.Name)
        Return If(result Is Nothing, False, True)
    End Function
    
    // Implement the TryGetMember method of the DynamicObject class for dynamic member calls.
    public override bool TryGetMember(GetMemberBinder binder,
                                      out object result) 
    {
        result = GetPropertyValue(binder.Name);
        return result == null ? false : true;
    }
    
  11. بعد أسلوبTryGetMember قم بإضافة التعليمة البرمجية التالية لتجاوز أسلوب TryInvokeMember فئة DynamicObject. يتم استدعاء الأسلوب TryInvokeMember عند طلب عضو من لفئة ديناميكية مع الوسيطات. وسيطة binder تحتوي على معلومات عن العضو المشار اليه ، و تشير الوسيطةresult إلى نتيجة إرجاع العضو المحدد. args تحتوي الوسيطة على صفيف من الوسائط التي تم تمريرها العضو. يقوم الأسلوب TryInvokeMember بإرجاع قيمة boolean التي ترجع true في حالة وجود العضو المطلوب; وإلا تقوم بإرجاع false.

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

    ' Implement the TryInvokeMember method of the DynamicObject class for 
    ' dynamic member calls that have arguments.
    Public Overrides Function TryInvokeMember(ByVal binder As InvokeMemberBinder,
                                              ByVal args() As Object,
                                              ByRef result As Object) As Boolean
    
        Dim StringSearchOption As StringSearchOption = StringSearchOption.StartsWith
        Dim trimSpaces = True
    
        Try
            If args.Length > 0 Then StringSearchOption = CType(args(0), StringSearchOption)
        Catch
            Throw New ArgumentException("StringSearchOption argument must be a StringSearchOption enum value.")
        End Try
    
        Try
            If args.Length > 1 Then trimSpaces = CType(args(1), Boolean)
        Catch
            Throw New ArgumentException("trimSpaces argument must be a Boolean value.")
        End Try
    
        result = GetPropertyValue(binder.Name, StringSearchOption, trimSpaces)
    
        Return If(result Is Nothing, False, True)
    End Function
    
    // Implement the TryInvokeMember method of the DynamicObject class for 
    // dynamic member calls that have arguments.
    public override bool TryInvokeMember(InvokeMemberBinder binder,
                                         object[] args,
                                         out object result)
    {
        StringSearchOption StringSearchOption = StringSearchOption.StartsWith;
        bool trimSpaces = true;
    
        try
        {
            if (args.Length > 0) { StringSearchOption = (StringSearchOption)args[0]; }
        }
        catch
        {
            throw new ArgumentException("StringSearchOption argument must be a StringSearchOption enum value.");
        }
    
        try
        {
            if (args.Length > 1) { trimSpaces = (bool)args[1]; }
        }
        catch
        {
            throw new ArgumentException("trimSpaces argument must be a Boolean value.");
        }
    
        result = GetPropertyValue(binder.Name, StringSearchOption, trimSpaces);
    
        return result == null ? false : true;
    }
    
  12. قم بحفظ الملف وإغلاقه.

لإنشاء نموذج ملف نص

  1. ينقر على اليمين المشروع DynamicSample ثم أشر إلى إضافةله ثم انقر فوق العنصر الجديد . في الجزء القوالب المثبتة حدد عامثم حدد القالب صواب ملف. اترك الاسم الافتراضي TextFile1.txt في المربع الاسم ثم انقر فوق صواب . تتم تمت الإضافة ملف نصي جديد إلى المشروع.

  2. قم بنسخ النص التالي إلى ملف TextFile1.txt.

    List of customers and suppliers
    
    Supplier: Lucerne Publishing (http://www.lucernepublishing.com/)
    Customer: Preston, Chris
    Customer: Hines, Patrick
    Customer: Cameron, Maria
    Supplier: Graphic Design Institute (http://www.graphicdesigninstitute.com/) 
    Supplier: Fabrikam, Inc. (http://www.fabrikam.com/) 
    Customer: Seubert, Roxanne
    Supplier: Proseware, Inc. (https://www.proseware.com/) 
    Customer: Adolphi, Stephan
    Customer: Koch, Paul
    
  3. قم بحفظ الملف وإغلاقه.

لإنشاء تطبيق نموذج يستخدم الكائنات ديناميكي المخصصة

  1. في مستكشف الحلول ، انقر نقرة مزدوجة فوق الملف Module1.vb إذا كنت تستخدم Visual Basic أو ملف Program.cs إذا كنت تستخدم Visual C#‎.

  2. قم بإضافة التعليمات البرمجية التالية صواب الإجراء الرئيسي صواب إنشاء مثيل ReadOnlyFile فئة الملف TextFile1.txt. تستخدم التعليمة البرمجية ربط في وقت التشغيل استدعاء الأعضاء ديناميكي واسترداد أسطر من النص تتضمن السلسلة "العميل".

    Dim rFile As Object = New ReadOnlyFile("..\..\TextFile1.txt")
    For Each line In rFile.Customer
        Console.WriteLine(line)
    Next
    Console.WriteLine("----------------------------")
    For Each line In rFile.Customer(StringSearchOption.Contains, True)
        Console.WriteLine(line)
    Next
    
    dynamic rFile = new ReadOnlyFile(@"..\..\TextFile1.txt");
    foreach (string line in rFile.Customer)
    {
        Console.WriteLine(line);
    }
    Console.WriteLine("----------------------------");
    foreach (string line in rFile.Customer(StringSearchOption.Contains, true))
    {
        Console.WriteLine(line);
    }
    
  3. قم بحفظ الملف ثم اضغط زر'Ctrl' + F5 إلى لبنية التطبيق وتشغيله.

راجع أيضًا:

المرجع

System.Dynamic

System.Dynamic.DynamicObject

الحيوي (C# مرجع)

المبادئ

ربط مبكر و المتأخر

موارد أخرى

Walkthroughs جديد (C# و Visual Basic)