Aracılığıyla paylaş


İzlenecek yol: C'de Dinamik Nesneler Oluşturma ve Kullanma#

Dinamik nesneler, derleme zamanında değil, çalışma zamanında özellikler ve yöntemler gibi üyeleri kullanıma sunar. Dinamik nesneler, statik bir tür veya biçimle eşleşmeyen yapılarla çalışacak nesneler oluşturmanıza olanak tanır. Örneğin, geçerli HTML işaretleme öğelerinin ve özniteliklerinin herhangi bir bileşimini içerebilen HTML Belge Nesne Modeli'ne (DOM) başvurmak için dinamik bir nesne kullanabilirsiniz. Her HTML belgesi benzersiz olduğundan, belirli bir HTML belgesinin üyeleri çalışma zamanında belirlenir. HTML öğesinin özniteliğine başvurmak için kullanılan yaygın bir yöntem, özniteliğin adını öğesinin GetProperty yöntemine geçirmektir. HTML öğesi id'in <div id="Div1"> özniteliğine başvurmak için önce <div> öğesine bir referans alır ve ardından divElement.GetProperty("id") kullanırsınız. Dinamik bir nesne kullanıyorsanız özniteliğine id olarak divElement.idbaşvurabilirsiniz.

Dinamik nesneler ayrıca IronPython ve IronRuby gibi dinamik dillere kolay erişim sağlar. Çalışma zamanında yorumlanacak dinamik bir betiğe başvurmak için dinamik bir nesne kullanabilirsiniz.

Geç bağlama kullanarak dinamik bir nesneye başvurursunuz. Geç bağlanan nesnenin türünü olarak dynamicbelirtirsiniz. Daha fazla bilgi için bkz. dinamik.

Ad alanında sınıfları System.Dynamic kullanarak özel dinamik nesneler oluşturabilirsiniz. Örneğin, bir ExpandoObject oluşturabilir ve çalışma zamanında bu nesnenin üyelerini belirtebilirsiniz. Kendi türünüzü DynamicObject sınıfını devralarak da oluşturabilirsiniz. Daha sonra, çalışma zamanı dinamik işlevselliği sağlamak için sınıfın DynamicObject üyelerini geçersiz kılabilirsiniz.

Bu makalede iki bağımsız rehber yer almaktadır.

  • Metin dosyasının içeriğini bir nesnenin özellikleri olarak dinamik olarak kullanıma sunan özel bir nesne oluşturun.
  • Bir IronPython kitaplığı kullanan bir proje oluşturun.

Önkoşullar

  • .NET masaüstü geliştirme iş yükünün yüklü olduğu Visual Studio 2022 sürüm 17.3 veya sonraki bir sürüm. Bu iş yükünü seçtiğinizde .NET 7 SDK'sı eklenir.

Uyarı

Bilgisayarınız, aşağıdaki yönergelerde bazı Visual Studio kullanıcı arabirimi öğeleri için farklı adlar veya konumlar gösterebilir. Sahip olduğunuz Visual Studio sürümü ve kullandığınız ayarlar bu öğeleri belirler. Daha fazla bilgi için bkz. IDE'yi Kişiselleştirme.

Özel Dinamik Nesne Oluşturma

İlk izlenecek yol, bir metin dosyasının içeriğini arayan özel bir dinamik nesne tanımlar. Dinamik özellik, aranacak metni belirtir. Örneğin, çağıran kod belirtiyorsa dynamicFile.Sample, dinamik sınıf dosyadan "Örnek" ile başlayan tüm satırları içeren genel bir dize listesi döndürür. Arama büyük/küçük harfe duyarlı olmadan gerçekleştirilir. Dinamik sınıf, isteğe bağlı iki bağımsız değişkeni de destekler. İlk bağımsız değişken, dinamik sınıfın satırın başında, sonunda veya satırda herhangi bir yerde eşleşme araması gerektiğini belirten bir arama seçeneği numaralandırma değeridir. İkinci bağımsız değişken, dinamik sınıfın aramadan önce her satırdaki baştaki ve sondaki boşlukları kırpması gerektiğini belirtir. Örneğin, çağıran kod dynamicFile.Sample(StringSearchOption.Contains) belirtiyorsa, dinamik sınıf bir satırda herhangi bir yerde "Örnek" arar. Çağırma kodu dynamicFile.Sample(StringSearchOption.StartsWith, false)'yi belirtirse, dinamik sınıf her satırın başında "örnek" ifadesini arar ve baştaki ve sondaki boşlukları silmez. Dinamik sınıfın varsayılan davranışı, her satırın başında bir eşleşme aramak ve baştaki ve sondaki boşlukları kaldırmaktır.

Özel dinamik sınıf oluşturma

Visual Studio'yu başlatın. Yeni proje oluştur'u seçin. Yeni proje oluştur iletişim kutusunda C# seçeneğini belirleyin, Konsol Uygulaması'nı ve ardından İleri'yi seçin. Yeni projenizi yapılandırın iletişim kutusunda DynamicSample olarak girin ve İleri'yi seçin. Ek bilgi iletişim kutusunda Hedef Çerçeve için .NET 7.0 (Geçerli) öğesini ve ardından Oluştur'u seçin. Çözüm Gezgini'nde DynamicSample projesine sağ tıklayın veSınıf> seçin. Ad kutusuna ReadOnlyFile yazın ve ardından Ekle seçeneğini seçin. ReadOnlyFile.cs dosyasının veya ReadOnlyFile.vb dosyasının en üstüne System.IO ve System.Dynamic ad alanlarını içeri aktarmak için aşağıdaki kodu ekleyin.

using System.IO;
using System.Dynamic;

Özel dinamik nesne, arama ölçütlerini belirlemek için bir sabit listesi kullanır. sınıf deyiminden önce aşağıdaki enum tanımını ekleyin.

public enum StringSearchOption
{
    StartsWith,
    Contains,
    EndsWith
}

Sınıf ifadesini, aşağıdaki kod örneğinde gösterildiği gibi DynamicObject sınıfını miras alacak şekilde güncelleyin.

class ReadOnlyFile : DynamicObject

Aşağıdaki kodu ReadOnlyFile sınıfına ekleyerek dosya yolu için özel bir alan ve ReadOnlyFile sınıfı için bir oluşturucu tanımlayın.

// 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;
}
  1. Aşağıdaki GetPropertyValue yöntemini ReadOnlyFile sınıfına ekleyin. GetPropertyValue yöntemi, giriş olarak arama ölçütlerini alır ve bu arama ölçütlerine uyan bir metin dosyasındaki satırları döndürür. ReadOnlyFile sınıfı tarafından sağlanan dinamik yöntemler, ilgili sonuçlarını almak için GetPropertyValue yöntemini çağırmak.
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;
}

GetPropertyValue yönteminden sonra TryGetMember sınıfının DynamicObject yöntemini geçersiz kılmak için aşağıdaki kodu ekleyin. Bir TryGetMember dinamik sınıfın üyesi istendiğinde ve hiçbir bağımsız değişken belirtilmediğinde yöntemi çağrılır. Bağımsız binder değişken, başvuruda bulunan üye hakkında bilgi içerir ve result bağımsız değişken, belirtilen üye için döndürülen sonuda başvurur. Belirtilen TryGetMember yöntemi, istenen üye mevcutsa true döndüren bir Boolean değeri döndürür; aksi takdirde false döndürür.

// 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;
}

TryGetMember yönteminden sonra TryInvokeMember sınıfının DynamicObject yöntemini geçersiz kılmak için aşağıdaki kodu ekleyin. Bağımsız değişkenlerle bir dinamik sınıfın üyesi istendiğinde, TryInvokeMember metot çağrılır. Bağımsız binder değişken, başvuruda bulunan üye hakkında bilgi içerir ve result bağımsız değişken, belirtilen üye için döndürülen sonuda başvurur. args argümanı, üyeye geçirilen argümanların bir dizisini içerir. Belirtilen TryInvokeMember yöntemi, istenen üye mevcutsa true döndüren bir Boolean değeri döndürür; aksi takdirde false döndürür.

Yöntemin TryInvokeMember özel sürümü, ilk bağımsız değişkenin, önceki adımda tanımladığınız StringSearchOption sabit listesinden bir değer olmasını bekler. yöntemi, TryInvokeMember ikinci bağımsız değişkenin Boole değeri olmasını bekler. Bağımsız değişkenlerden biri veya her ikisi de geçerli değerlerse, GetPropertyValue yöntemine sonuçları almak üzere geçirilir.

// 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;
}

Dosyayı kaydedin ve kapatın.

Örnek metin dosyası oluşturma

Çözüm Gezgini'nde DynamicSample projesine sağ tıklayın veYeni Öğe Ekle'yi> seçin. Yüklü Şablonlar bölmesinde Genel'i ve ardından Metin Dosyası şablonunu seçin. Ad kutusunda varsayılan TextFile1.txt adını bırakın ve Ekle'yi seçin. Aşağıdaki metni TextFile1.txt dosyasına kopyalayın.

List of customers and suppliers

Supplier: Lucerne Publishing (https://www.lucernepublishing.com/)
Customer: Preston, Chris
Customer: Hines, Patrick
Customer: Cameron, Maria
Supplier: Graphic Design Institute (https://www.graphicdesigninstitute.com/)
Supplier: Fabrikam, Inc. (https://www.fabrikam.com/)
Customer: Seubert, Roxanne
Supplier: Proseware, Inc. (http://www.proseware.com/)
Customer: Adolphi, Stephan
Customer: Koch, Paul

Dosyayı kaydedin ve kapatın.

Özel dinamik nesneyi kullanan örnek bir uygulama oluşturma

Çözüm Gezgini'ndeProgram.cs dosyasına çift tıklayın. Main dosyasının ReadOnlyFile sınıfının bir örneğini oluşturmak için yordama aşağıdaki kodu ekleyin. Kod, dinamik üyeleri çağırmak ve "Customer" dizesini içeren metin satırlarını almak için geç bağlama kullanır.

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);
}

Dosyayı kaydedin ve uygulamayı derlemek ve çalıştırmak için Ctrl

Dinamik dil kitaplığı çağırma

Aşağıdaki kılavuz, ironpython dinamik dilinde yazılmış bir kitaplığa erişen bir proje oluşturur.

Özel dinamik sınıf oluşturmak için

Visual Studio'da DosyaYeni Proje'yi>> seçin. Yeni proje oluştur iletişim kutusunda C# seçeneğini belirleyin, Konsol Uygulaması'nı ve ardından İleri'yi seçin. Yeni projenizi yapılandırın iletişim kutusunda DynamicIronPythonSample olarak girin ve İleri'yi seçin. Ek bilgi iletişim kutusunda Hedef Çerçeve için .NET 7.0 (Geçerli) öğesini ve ardından Oluştur'u seçin. IronPython NuGet paketini yükleyin. Program.cs dosyasını düzenleyin. Dosyanın en üstüne, IronPython kitaplıklarından Microsoft.Scripting.Hosting ve IronPython.Hosting ad alanlarını ve System.Linq ad alanını içeri aktarmak için aşağıdaki kodu ekleyin.

using System.Linq;
using Microsoft.Scripting.Hosting;
using IronPython.Hosting;

Main yöntemine aşağıdaki kodu ekleyerek IronPython kitaplıklarını barındıracak yeni Microsoft.Scripting.Hosting.ScriptRuntime bir nesne oluşturun. ScriptRuntime nesnesi IronPython kitaplık modülünü random.py yükler.

// Set the current directory to the IronPython libraries.
System.IO.Directory.SetCurrentDirectory(
   Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) +
   @"\IronPython 2.7\Lib");

// Create an instance of the random.py IronPython library.
Console.WriteLine("Loading random.py");
ScriptRuntime py = Python.CreateRuntime();
dynamic random = py.UseFile("random.py");
Console.WriteLine("random.py loaded.");

random.py modülünü yüklemek için koddan sonra aşağıdaki kodu ekleyerek bir tamsayı dizisi oluşturun. Dizi, dizideki shuffle değerleri rastgele sıralayan random.py modülünün yöntemine geçirilir.

// Initialize an enumerable set of integers.
int[] items = Enumerable.Range(1, 7).ToArray();

// Randomly shuffle the array of integers by using IronPython.
for (int i = 0; i < 5; i++)
{
    random.shuffle(items);
    foreach (int item in items)
    {
        Console.WriteLine(item);
    }
    Console.WriteLine("-------------------");
}

Dosyayı kaydedin ve uygulamayı derlemek ve çalıştırmak için Ctrl

Ayrıca bakınız