Akademi C# · Pelajaran

Senario metapengaturcaraan ringan

Pembantu dipacu atribut: label paparan, pengesahan keperluan, pengaktif pembina mini dan pensirian seperti CSV dengan petua keselamatan yang jelas.

Pelajaran 3 daripada 38 langkah

Senario metapengaturcaraan ringan ialah pelajaran Akademi C# percuma di CoddyKit. Ini ialah pelajaran 3 daripada 3. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Akademi C#, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Akademi C# merangkumi sejumlah 3 pelajaran.

Pelan & skop

Matlamat: Kawal tingkah laku kecil dengan atribut.

  • Petakan label
  • Sahkan medan wajib
  • Pengaktif DI mini
  • Sirikan kepada teks seperti CSV

Label atribut

Hiasi sifat dengan DisplayName dan gunakan refleksi terhadapnya untuk mencetak label yang mudah difahami.

using System;
using System.Reflection;

[AttributeUsage(AttributeTargets.Property)]
public sealed class DisplayNameAttribute : Attribute
{
  public string Text { get; private set; }
  public DisplayNameAttribute(string text) { Text = text; }
}

public sealed class User
{
  [DisplayName("User Id")]
  public int Id { get; set; }

  [DisplayName("Full Name")]
  public string Name { get; set; }
}

public class Program
{
  static void PrintWithLabels(object o)
  {
    if (o == null) throw new ArgumentNullException("o");
    Type t = o.GetType();
    foreach (PropertyInfo p in t.GetProperties())
    {
      object[] at = p.GetCustomAttributes(typeof(DisplayNameAttribute), false);
      string label = at.Length > 0 ? ((DisplayNameAttribute)at[0]).Text : p.Name;
      object val = p.GetValue(o, null);
      Console.WriteLine(label + ": " + (val == null ? "null" : val.ToString()));
    }
  }

  public static void Main(string[] args)
  {
    User u = new User { Id = 1, Name = "Ada" };
    PrintWithLabels(u);
  }
}

Pengesahan atribut

Tandakan sifat dengan Required; pengesah kecil menyemak dan melaporkan medan pertama yang tiada.

using System;
using System.Reflection;

[AttributeUsage(AttributeTargets.Property)]
public sealed class RequiredAttribute : Attribute { }

public sealed class Product
{
  [Required] public string Name { get; set; }
  public decimal Price { get; set; }
}

public class Program
{
  static bool Validate(object obj, out string error)
  {
    error = null;
    if (obj == null) { error = "object is null"; return false; }

    Type t = obj.GetType();
    foreach (PropertyInfo p in t.GetProperties())
    {
      object[] req = p.GetCustomAttributes(typeof(RequiredAttribute), false);
      if (req.Length > 0)
      {
        object v = p.GetValue(obj, null);
        if (v == null || (v is string && string.IsNullOrEmpty((string)v)))
        {
          error = "Required property missing: " + p.Name;
          return false;
        }
      }
    }
    return true;
  }

  public static void Main(string[] args)
  {
    Product ok = new Product { Name = "Mouse", Price = 10m };
    Product bad = new Product { Name = null, Price = 5m };

    string e;
    Console.WriteLine(Validate(ok, out e) ? "OK" : e);
    Console.WriteLine(Validate(bad, out e) ? "OK" : e);
  }
}

Pengaktif mini

Pengaktif kecil memadankan nama dengan setiap parameter pembina. Berikan nilai lalai apabila tiada.

using System;
using System.Reflection;
using System.Collections.Generic;

public sealed class Repo { public string Name; public Repo(string name){ Name = name; } }

public sealed class Service
{
  public Repo R; public int Timeout;
  public Service(Repo repo, int timeout){ R = repo; Timeout = timeout; }
}

public class Program
{
  static object CreateWithArgs(Type t, IDictionary<string, object> args)
  {
    if (t == null) throw new ArgumentNullException("t");
    if (args == null) args = new Dictionary<string, object>();

    ConstructorInfo[] ctors = t.GetConstructors();
    if (ctors.Length == 0) throw new InvalidOperationException("No public constructor");

    ConstructorInfo ci = ctors[0];
    ParameterInfo[] ps = ci.GetParameters();
    object[] argv = new object[ps.Length];

    for (int i = 0; i < ps.Length; i++)
    {
      object val;
      if (args.TryGetValue(ps[i].Name, out val)) argv[i] = val;
      else if (ps[i].ParameterType.IsValueType) argv[i] = Activator.CreateInstance(ps[i].ParameterType);
      else argv[i] = null;
    }
    return ci.Invoke(argv);
  }

  public static void Main(string[] args)
  {
    IDictionary<string, object> map = new Dictionary<string, object>();
    map["repo"] = new Repo("Main");
    map["timeout"] = 30;

    Service s = (Service)CreateWithArgs(typeof(Service), map);
    Console.WriteLine(s.R.Name + " / " + s.Timeout);
  }
}

CSV menggunakan atribut

Susun lajur dengan CsvOrder dan lakukan pelolosan koma serta tanda petikan dengan betul.

using System;
using System.Reflection;
using System.Text;
using System.Globalization;

[AttributeUsage(AttributeTargets.Property)]
public sealed class CsvOrderAttribute : Attribute
{
  public int Index { get; private set; }
  public CsvOrderAttribute(int index){ Index = index; }
}

public sealed class Row
{
  [CsvOrder(0)] public int Id { get; set; }
  [CsvOrder(1)] public string Name { get; set; }
  [CsvOrder(2)] public decimal Price { get; set; }
}

public class Program
{
  static int GetIndex(PropertyInfo p)
  {
    object[] at = p.GetCustomAttributes(typeof(CsvOrderAttribute), false);
    return at.Length > 0 ? ((CsvOrderAttribute)at[0]).Index : Int32.MaxValue;
  }

  static string ToCsv(object o)
  {
    if (o == null) throw new ArgumentNullException("o");
    Type t = o.GetType();
    PropertyInfo[] props = t.GetProperties();

    Array.Sort(props, delegate(PropertyInfo a, PropertyInfo b)
    {
      int ia = GetIndex(a), ib = GetIndex(b);
      return ia.CompareTo(ib);
    });

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < props.Length; i++)
    {
      object v = props[i].GetValue(o, null);
      string cell = v == null ? "" : Convert.ToString(v, CultureInfo.InvariantCulture);

      if (i > 0) sb.Append(",");
      sb.Append(cell);
    }
    return sb.ToString();
  }

  public static void Main(string[] args)
  {
    Row r = new Row { Id = 7, Name = "Cable, HDMI", Price = 12.5m };
    Console.WriteLine(ToCsv(r));
  }
}

Petua & keselamatan

Petua:

  • Utamakan typeof dan metadata yang dicache pada laluan yang kerap digunakan.
  • Sahkan ahli sebelum GetValue atau Invoke.
  • Pastikan pembantu kecil dan diuji unit.
  • Gagal dengan segera menggunakan mesej yang membantu.

Panduan refleksi

Semakan pantas: Apakah peraturan selamat apabila menggunakan refleksi untuk metaprograman ringan?

Ringkasan

Ringkasan: Atribut boleh memacu pemetaan, pengesah, pengaktif dan pensiri kecil. Pastikan penggunaan refleksi minimum dan selamat.

Percuma untuk bermula

Pelajari C# dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
93
Pelajaran
346

Soalan Lazim

Adakah pelajaran “Senario metapengaturcaraan ringan” percuma?

Ya — teks penuh “Senario metapengaturcaraan ringan” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Akademi C#, tingkat taraf kepada CoddyKit PRO. Kursus Akademi C# merangkumi sejumlah 3 pelajaran.

Apakah yang akan saya pelajari dalam “Senario metapengaturcaraan ringan”?

Pembantu dipacu atribut: label paparan, pengesahan keperluan, pengaktif pembina mini dan pensirian seperti CSV dengan petua keselamatan yang jelas. Anda berlatih Akademi C# menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Akademi C#?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Akademi C# di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 3 daripada 3.

Berapa lamakah pelajaran “Senario metapengaturcaraan ringan” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Akademi C# ini?

Ya. Setiap pelajaran Akademi C# menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Type, MethodInfo, pengaktifan, atribut tersuai
  2. Maklumat peringkat sumber (atribut Caller)
  3. Senario metapengaturcaraan ringan
← Kembali ke Akademi C#