가벼운 메타프로그래밍 시나리오
특성 기반 도우미를 만듭니다. 표시 레이블, 필수 값 검증, 간단한 생성자 활성화기, 명확한 안전 팁과 함께하는 CSV 유사 직렬화를 다룹니다.
가벼운 메타프로그래밍 시나리오은(는) CoddyKit의 무료 C# Academy 강의입니다. 이것은 3개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 C# Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. C# Academy 강의에는 총 3개의 강의가 포함되어 있습니다.
계획 및 범위
목표: 특성으로 작은 동작을 제어합니다.
- 레이블 매핑
- 필수 필드 검증
- 간단한 DI 활성화 도구
- CSV와 유사한 텍스트로 직렬화
특성 레이블
속성에 DisplayName을 지정하고 이를 리플렉션으로 읽어 알기 쉬운 레이블을 출력하십시오.
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);
}
}
특성 검증
속성에 Required를 표시하면 간단한 검증기가 확인 후 처음 누락된 필드를 보고합니다.
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);
}
}
간단한 활성화 도구
간단한 활성화 도구가 이름을 각 생성자 매개 변수에 매핑합니다. 값이 없으면 기본값을 제공하십시오.
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
CsvOrder로 열 순서를 지정하고 쉼표와 따옴표를 올바르게 이스케이프하십시오.
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));
}
}
팁 및 안전 수칙
팁:
- 자주 실행되는 경로에서는 typeof와 캐시된 메타데이터를 우선 사용하십시오.
- GetValue 또는 Invoke를 호출하기 전에 멤버를 검증하십시오.
- 도우미를 작게 유지하고 단위 테스트를 거치게 하십시오.
- 유용한 메시지와 함께 즉시 실패하도록 하십시오.
리플렉션 지침
복습
복습: 특성으로 작은 매퍼, 검증기, 활성화 도구, 직렬 변환기를 제어할 수 있습니다. 리플렉션을 최소한으로 사용하고 안전하게 유지하십시오.
자주 묻는 질문
“가벼운 메타프로그래밍 시나리오” 강의는 무료인가요?
네 — “가벼운 메타프로그래밍 시나리오” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C# Academy 강의 전체를 잠금 해제할 수 있습니다. C# Academy 강의에는 총 3개의 강의가 포함되어 있습니다.
“가벼운 메타프로그래밍 시나리오”에서 뭘 배우나요?
특성 기반 도우미를 만듭니다. 표시 레이블, 필수 값 검증, 간단한 생성자 활성화기, 명확한 안전 팁과 함께하는 CSV 유사 직렬화를 다룹니다. 브라우저에서 직접 실행하는 실습 코드로 C# Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
C# Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 C# Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 3개 중 3번째 강의입니다.
“가벼운 메타프로그래밍 시나리오” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 C# Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 C# Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- Type, MethodInfo, 활성화와 사용자 지정 특성
- 소스 수준 정보(Caller 특성)
- 가벼운 메타프로그래밍 시나리오