#DevSecOps ~ Bunjo
Meta Programlama Nedir ve Türleri Nelerdir?

Bir programın diğer programları veya kendisini manipüle etmesine, analiz edebilmesine veya üretebilme sürecine meta programlama denir.
Programların dinamik sağlar ve genellikle derleme zamanında veya çalışma zamanında kod üretmek, değiştirmek veya incelemek için kullanılır.
İyi güzel fakat hangi alanlarda kullanılır bu meta programlama? diye sorarsanız,
Kütüphane ve araç geliştirmelerinde, hata ayıklama ve performans analizi işlevi gören programlarda kullanıldığını söyleyebilirim
Meta programlama gibi geniş bir kavramı burada tamamen anlatmam mümkün değildir. Basit şekilde meta programlanın türlerinden bahsedeyim:
Makro Programlama

Makro metaprogramlama, programın belirli bölümlerinin, makro adı verilen önceden tanımlanmış kurallar ve kalıplar kullanılarak genişletilmesini sağlar. Bu makrolar, derleyici tarafından derleme zamanında işlenir ve kodun genişletilmesi, değiştirilmesi veya yeniden yazılması sağlanır.
Örnek makro tanımı:
C:
#include <stdio.h>
#define PI 3.14159
#define SQUARE(x) ((x) * (x))
int main() {
printf("PI: %f\n", PI);
printf("Square of 5: %d\n", SQUARE(5));
return 0;
}
Fonksiyonlar için örnek makro tanımı:
C:
#include <stdio.h>
// Koşullu makro
#define DEBUG
#ifdef DEBUG
#define LOG(message) printf("DEBUG: %s\n", message)
#else
#define LOG(message)
#endif
int main() {
LOG("Program started");
printf("Hello, World!\n");
LOG("Program ended");
return 0;
}
Şablon Meta Programlaması (Template Metaprogramming)

Template metaprogramming, özellikle C++ dilinde kullanılan güçlü bir tekniktir. Bu teknik, derleme zamanında template (şablon) kullanarak programlama yapmayı ve bu sayede yüksek performanslı ve genel kodlar oluşturmayı sağlar. Kafanızda karmaşık bir şey olarak tanımlamanıza gerek yok, faktöriyel hesaplaması yapan bir kod bile bu başlık altında incelenebilir.
C:
#include <iostream>
// Template metaprogramming ile faktöriyel hesaplama
template <int N>
struct Factorial {
static const int value = N * Factorial<N - 1>::value;
};
template <>
struct Factorial<0> {
static const int value = 1;
};
int main() {
std::cout << "Factorial of 5: " << Factorial<5>::value << std::endl;
return 0;
}
Örnek:
C:
#include <iostream>
// Template metaprogramming ile Fibonacci serisi hesaplama
template <int N>
struct Fibonacci {
static const int value = Fibonacci<N - 1>::value + Fibonacci<N - 2>::value;
};
template <>
struct Fibonacci<0> {
static const int value = 0;
};
template <>
struct Fibonacci<1> {
static const int value = 1;
};
int main() {
std::cout << "Fibonacci sequence (up to 10): ";
for (int i = 0; i <= 10; ++i) {
std::cout << Fibonacci<i>::value << " ";
}
std::cout << std::endl;
return 0;
}
Örnek:
C:
#include <iostream>
// Tip listesi tanımlaması
template <typename... Types>
struct TypeList;
// Tip listesi yazdırma
template <typename T, typename... Rest>
struct TypeList<T, Rest...> {
static void print() {
std::cout << typeid(T).name() << " ";
TypeList<Rest...>::print();
}
};
template <>
struct TypeList<> {
static void print() {
std::cout << std::endl;
}
};
int main() {
std::cout << "Type List: ";
TypeList<int, double, char>::print();
return 0;
}
Yansıtma (Reflection)

Basit ve temel olarak, bir programın çalışma zamanında kendi yapısını incelemesi, analiz etmesi, değiştirmesi veya hatta yeni nesneler oluşturması yeteneğidir.
Örnek:
Java:
import java.lang.reflect.Method;
public class ReflectionExample {
public void sayHello(String name) {
System.out.println("Hello, " + name + "!");
}
public static void main(String[] args) throws Exception {
Class<?> clazz = ReflectionExample.class;
// Tüm metotları al
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println("Method: " + method.getName());
}
// Belirli bir metodu al
Method method = clazz.getMethod("sayHello", String.class);
System.out.println("Method: " + method.getName());
}
}
Türlere bağlı olarak örnekler çoğaltılabilir. Kafanızda meta programlama ile ilgili şeyler bile oluşması şu aşamada yeterli olacaktır.
Şimdi sıra asıl konumuz olan C# ile meta programlamanın nasıl olduğu olacaktır.
C# ile Meta Programlama

Type Reflection (Tür Yansıtma)

Bir sınıfın tüm metotlarını listelemek:
Şimdi sıra asıl konumuz olan C# ile meta programlamanın nasıl olduğu olacaktır.
C# ile Meta Programlama

Type Reflection (Tür Yansıtma)

Bir sınıfın tüm metotlarını listelemek:
C#:
using System;
using System.Reflection;
public class MyClass
{
public void Method1() { }
public void Method2() { }
public void Method3() { }
}
class Program
{
static void Main()
{
Type type = typeof(MyClass);
MethodInfo[] methods = type.GetMethods();
foreach (var method in methods)
{
Console.WriteLine(method.Name);
}
}
}
Bir sınıfın özelliklerine erişmek:
C#:
using System;
using System.Reflection;
public class MyClass
{
public int MyProperty { get; set; }
private string _name;
public void Method() { }
}
class Program
{
static void Main()
{
Type type = typeof(MyClass);
PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var property in properties)
{
Console.WriteLine(property.Name);
}
}
}
Constructor yoluyla yeni bir nesne oluşturmak:
C#:
using System;
using System.Reflection;
public class MyClass
{
public MyClass(int value)
{
Console.WriteLine("Constructor called with value: " + value);
}
}
class Program
{
static void Main()
{
Type type = typeof(MyClass);
ConstructorInfo ctor = type.GetConstructor(new[] { typeof(int) });
object instance = ctor.Invoke(new object[] { 10 });
}
}
C#:
using System;
[AttributeUsage(AttributeTargets.Class)]
public class CustomAttribute : Attribute
{
public string Description { get; set; }
public CustomAttribute(string description)
{
Description = description;
}
}
[CustomAttribute("This is a custom attribute")]
public class MyClass
{
public void Method() { }
}
class Program
{
static void Main()
{
Type type = typeof(MyClass);
CustomAttribute attribute = (CustomAttribute)Attribute.GetCustomAttribute(type, typeof(CustomAttribute));
Console.WriteLine("Description: " + attribute.Description);
}
}
Metot üzerindeki özniteliği sorgulamak:
C#:
using System;
[AttributeUsage(AttributeTargets.Method)]
public class ExecuteMeAttribute : Attribute
{
public string Message { get; }
public ExecuteMeAttribute(string message)
{
Message = message;
}
}
public class MyClass
{
[ExecuteMe("Executing this method")]
public void Method() { }
}
class Program
{
static void Main()
{
Type type = typeof(MyClass);
MethodInfo method = type.GetMethod("Method");
ExecuteMeAttribute attribute = (ExecuteMeAttribute)Attribute.GetCustomAttribute(method, typeof(ExecuteMeAttribute));
Console.WriteLine("Message: " + attribute.Message);
}
}
Özniteliği dinamik olarak ekleyerek yönetmek:
C#:
using System;
[AttributeUsage(AttributeTargets.Class)]
public class CustomAttribute : Attribute
{
public string Description { get; set; }
public CustomAttribute(string description)
{
Description = description;
}
}
[CustomAttribute("Initial description")]
public class MyClass
{
public void Method() { }
}
class Program
{
static void Main()
{
Type type = typeof(MyClass);
CustomAttribute attribute = (CustomAttribute)Attribute.GetCustomAttribute(type, typeof(CustomAttribute));
Console.WriteLine("Initial Description: " + attribute.Description);
// Yeni bir öznitelik ekleyerek değiştirme
CustomAttribute newAttribute = new CustomAttribute("Updated description");
Attribute.SetCustomAttribute(type, newAttribute);
attribute = (CustomAttribute)Attribute.GetCustomAttribute(type, typeof(CustomAttribute));
Console.WriteLine("Updated Description: " + attribute.Description);
}
}
C#:
using System;
using System.Reflection;
public class MyClass
{
public void SayHello(string name)
{
Console.WriteLine("Hello, " + name + "!");
}
}
class Program
{
static void Main()
{
Type type = typeof(MyClass);
MyClass obj = Activator.CreateInstance(type) as MyClass;
MethodInfo method = type.GetMethod("SayHello");
method.Invoke(obj, new object[] { "Alice" });
}
}
Metot parametrelerini dinamik olarak belirlemek:
C#:
using System;
using System.Reflection;
public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
}
class Program
{
static void Main()
{
Type type = typeof(Calculator);
object obj = Activator.CreateInstance(type);
MethodInfo method = type.GetMethod("Add");
int result = (int)method.Invoke(obj, new object[] { 10, 5 });
Console.WriteLine("Result: " + result);
}
}
Generic metotları çağırmak:
C#:
using System;
using System.Reflection;
public class Printer
{
public void Print<T>(T value)
{
Console.WriteLine(value);
}
}
class Program
{
static void Main()
{
Type type = typeof(Printer);
object obj = Activator.CreateInstance(type);
MethodInfo method = type.GetMethod("Print");
MethodInfo genericMethod = method.MakeGenericMethod(typeof(int));
genericMethod.Invoke(obj, new object[] { 123 });
}
}
C#:
using System;
using System.Reflection;
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
class Program
{
static void Main()
{
Person person = new Person { Name = "Alice", Age = 30 };
Type type = typeof(Person);
PropertyInfo[] properties = type.GetProperties();
foreach (var property in properties)
{
Console.WriteLine(property.Name + ": " + property.GetValue(person));
}
}
}
Özellik değerini dinamik olarak ayarlamak:
C#:
using System;
using System.Reflection;
public class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
}
class Program
{
static void Main()
{
Product product = new Product { Name = "Laptop", Price = 1500 };
Type type = typeof(Product);
PropertyInfo property = type.GetProperty("Price");
property.SetValue(product, 1700);
Console.WriteLine("New Price: " + product.Price);
}
}
Özel erişim belirleyicisi (private, protected) olan özelliklere erişmek:
C#:
using System;
using System.Reflection;
public class Car
{
private int _year;
public Car(int year)
{
_year = year;
}
}
class Program
{
static void Main()
{
Car car = new Car(2020);
Type type = typeof(Car);
FieldInfo field = type.GetField("_year", BindingFlags.NonPublic | BindingFlags.Instance);
int year = (int)field.GetValue(car);
Console.WriteLine("Year of manufacture: " + year);
}
}
C#:
using System;
using System.Reflection;
public class MyClass
{
public MyClass() { }
public MyClass(int value) { }
public MyClass(string text) { }
}
class Program
{
static void Main()
{
Type type = typeof(MyClass);
ConstructorInfo[] constructors = type.GetConstructors();
foreach (var ctor in constructors)
{
Console.WriteLine("Constructor: " + ctor.Name);
}
}
}
Parametreli bir constructor ile yeni bir nesne oluşturmak:
C#:
using System;
using System.Reflection;
public class MyClass
{
public MyClass(int value)
{
Console.WriteLine("Constructor called with value: " + value);
}
}
class Program
{
static void Main()
{
Type type = typeof(MyClass);
ConstructorInfo ctor = type.GetConstructor(new[] { typeof(int) });
object instance = ctor.Invoke(new object[] { 10 });
}
}
C#:
using System;
using System.Reflection;
class Program
{
static void Main()
{
Assembly assembly = Assembly.GetExecutingAssembly();
Type[] types = assembly.GetTypes();
foreach (var type in types)
{
Console.WriteLine("Type: " + type.FullName);
}
}
}
Bir assembly içindeki belirli bir türü yüklemek:
C#:
using System;
using System.Reflection;
class Program
{
static void Main()
{
Assembly assembly = Assembly.LoadFile(@"dll dosya dizininiz");
Type type = assembly.GetType("Namespace.ClassName");
Console.WriteLine("Type: " + type.FullName);
}
}
Kapanış

Bu yazının içeriği, internette bulunan çeşitli dokümanlardan yararlanılarak oluşturulmuş olup düzen için yapay zekalardan yardım alınmıştır.
Yazıda bulunan kodların büyük bir kısmı alıntıdır ve bana ait değildir. Bu yazıya yardımcı olan herkese teşekkür ederim.
Çeşitli kısımlarda, gözden kaçan hatalar olabilir.
Konuyu okuyup gitmek yerine, emeğe saygı duyup bir yorum yazabilir ve bir beğeni atabilirsiniz.
Okuyan herkese teşekkürlerimi sunar, iyi forumlar dilerim.
Son düzenleme:

