پشتیبانی از انقیاد پویا در سیشارپ
نویسنده: پرهام دستغیب
تاریخ: ۱۳۹۷/۰۴/۲۱ ۱۹:۵۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
string text = “String value”; int textLength = text.Length; int textMonth = text.Month; // won’t compile
public interface IGeometricShape
{
double Circumference { get; }
double Area { get; }
}
public class Square : IGeometricShape
{
public double Side { get; set; }
public double Circumference => 4 * Side;
public double Area => Side * Side;
}
public class Circle : IGeometricShape
{
public double Radius { get; set; }
public double Circumference => 2 * Math.PI * Radius;
public double Area => Math.PI * Radius * Radius;
}
IGeometricShape circle = new Circle { Radius = 1 };
Square square = ((Square)circle); // no compiler error
var side = square.Side; dynamic text = “String value”; int textLength = text.Length; int textMonth = text.Month; // throws exception at runtime
public dynamic GetAnonymousType()
{
return new
{
Name = “John”,
Surname = “Doe”,
Age = 42
};
}
dynamic value = GetAnonymousType();
Console.WriteLine($”{value.Name} {value.Surname}, {value.Age}”); string json = @"
{
""name"": ""John"",
""surname"": ""Doe"",
""age"": 42
}";
dynamic value = JObject.Parse(json);
Console.WriteLine($"{ value.name} { value.surname}, { value.age}"); dynamic person = new ExpandoObject();
person.Name = "John";
person.Surname = "Doe";
person.Age = 42;
person.ToString = (Func<string>)(() => $”{person.Name} {person.Surname}, {person. Age}”);
Console.WriteLine($"{ person.Name}{ person.Surname}, { person.Age}"); برای اینکه ببینیم در زمان اجرا چه اعضایی به این شی اضافه شده، میتوان نمونه ساخته شده از آن را به نوع <IDictionary<string, object تبدیل و در یک حلقه به آنها دسترسی پیدا کرد. از همین طریق هم میشود عضوی را حذف کرد.
var dictionary = (IDictionary<string, object>)person;
foreach (var member in dictionary)
{
Console.WriteLine($”{member.Key} = {member.Value}”);
}
dictionary.Remove(“ToString”); از آنجایی که ExpandoObject برای سناریوهای ساده کاربرد دارد و کنترل کمتری بر روی اعضا و نمونههای ایجاد شدهی توسط آن داریم، میتوان از شیء DynamicObject استفاده کرد؛ البته نیاز به کدنویسی بیشتری دارد. پیادهسازی اعضا برای شیء DynamicObject در یک کلاس صورت میگیرد که در زیر آورده شدهاست:
class MyDynamicObject : DynamicObject
{
private readonly Dictionary<string, object> members = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (members.ContainsKey(binder.Name))
{
result = members[binder.Name];
return true;
}
else
{
result = null;
return false;
}
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
members[binder.Name] = value;
return true;
}
public bool RemoveMember(string name)
{
return members.Remove(name);
}
}
dynamic person = new MyDynamicObject();
person.Name = “John”;
person.Surname = “Doe”;
person.Age = 42;
person.AsString = (Func<string>)(() => $”{person.Name} {person.Surname}, {person.
Age}”); public static class ExpandoXml
{
public static dynamic AsExpando(this XDocument document)
{
return CreateExpando(document.Root);
}
private static dynamic CreateExpando(XElement element)
{
var result = new ExpandoObject() as IDictionary<string, object>;
if (element.Elements().Any(e => e.HasElements))
{
var list = new List<ExpandoObject>();
result.Add(element.Name.ToString(), list);
foreach (var childElement in element.Elements())
{
list.Add(CreateExpando(childElement));
}
}
else
{
foreach (var leafElement in element.Elements())
{
result.Add(leafElement.Name.ToString(), leafElement.Value);
}
}
return result;
}
} class Program
{
static void Main(string[] args)
{
var doc1 = XDocument.Load("Employees.xml");
foreach (var element in doc1.Element("Employees").Elements("Employee"))
{
Console.WriteLine(element.Element("FirstName").Value);
}
var doc2 = XDocument.Load("Employees.xml").AsExpando();
foreach (var employee in doc2.Employees)
{
Console.WriteLine(employee.FirstName);
}
}
}