dynamic person1 = new Person() { Name = "Vejon", Age = 28 };
Console.WriteLine(person1);
Console.WriteLine(person1.getSalary(28.09, "int"));
dynamic person2 = new Person() { Name = "WinStyle", Age = "yigirma yetti yosh" };
Console.WriteLine(person2);
Console.WriteLine(person2.getSalary(30, "string"));
2 §. DynamicObject va Expandoobject.
O'zingizning dinamik ob'ektingizni yaratishingiz kerak bo'lsa buning uchun ikkita variant mavjud: DynamicObject-dan meros olish yoki ExpandoObject-dan foydalanish. DynamicObject-dan foydalanish biroz ko'proq mehnat talab qiladi, chunki siz bir nechta usullarni bekor qilishingiz kerak. ExpandoObject - bu muhrlangan (muhrlangan) sinf, foydalanishga tayyor.
DynamicObject
Foydalanuvchini ifodalovchi ob'ektni ko'rib chiqing. Odatda bu ism va yosh uchun xususiyatlarni belgilaydi. Endi siz ob'ekt qanday xususiyatlarga ega bo'lishi va u qanday usullarni qo'llab-quvvatlashi haqida oldindan ma'lumotga ega bo'lmagan tizimga asoslanib, bunday ob'ektni ish vaqtida qurish imkoniyatiga ega bo'lishni xohlaysiz deylik. DynamicObject-ga asoslangan ob'ekt aynan shuni ta'minlay oladi. Bu funksionallik juda kamdan-kam talab qilinadi, ammo hozirgacha C# tili bunga ruxsat bermas edi.
Birinchidan, DynamicObject qanday ko'rinishini ko'rib chiqamiz:
using System;
using System.Dynamic;
using System.Collections.Generic;
namespace ConsoleApplication1
{
class MyDynamicObject : DynamicObject
{
Dictionary _dynamic = new Dictionary();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
bool qq = false;
result = null;
if (_dynamic.ContainsKey(binder.Name))
{
result = _dynamic[binder.Name];
qq = true;
}
else
{
result = "Свойство не найдено!";
qq = false;
}
return qq;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
_dynamic[binder.Name] = value;
return true;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
dynamic method = _dynamic[binder.Name];
result = method((DateTime)args[0]);
return result != null;
}
}
class Program
{
static void Main()
{
}
}
}
Bu misol uchta usulni bekor qiladi: TrySetMember, TryGetMember va TryInvokeMember.
TrySetMember ob'ektga yangi usul, xususiyat yoki maydon qo'shadi. Ushbu misolda a'zolar haqidagi ma'lumotlar Lug'at ob'ektida saqlanadi. TrySetMember-ga uzatilgan SetMemberBinder obyekti Lug'atdagi elementni aniqlash uchun foydalaniladigan Name xususiyatini o'z ichiga oladi.
TryGetMember lug'atda saqlangan ob'ektni GetMemberBinder'dan Name xususiyatiga asoslangan holda oladi.
Birinchidan, System.Dynamic.DynamicObject klassi nima ekanligini ko'rib chiqamiz. Bu sinf odatiy ko'rinadi - siz, masalan, undan meros bo'lib, uning bir yoki bir nechta usullarini ortiqcha yuklashingiz mumkin. Faqat bu erda bir nechta qiyin usullar mavjud ... keling, batafsil ko'rib chiqaylik.
Birinchidan, keling, DO test ob'ektini yaratamiz va DynamicObject-dan meros qilib olamiz:
class DO : DynamicObject {}
Endi dinamik kalit so'zdan foydalanib, biz hech qanday pushaymon bo'lmasdan ushbu ob'ekt bo'yicha ba'zi usullarni chaqirishimiz mumkin:
dinamik dobj = yangi DO();
dobj.NonExistentMethod();
O'ylab ko'ring, biz nima olamiz. Biz RuntimeBinderException deb nomlangan narsani olamiz va bu xabar.
"DynamicObjectAbuse.DO" "NonExistentMethod" uchun ta'rifni o'z ichiga olmaydi
Bu tabiiy, chunki Bizning sinfimiz oddiygina NonExistentMethod() usuliga ega emas. Qizig'i shundaki, u hech qachon bo'lmasligi mumkin. Bu DynamicObject-ning butun nuqtasi - sinfda mavjud bo'lmagan xususiyatlar va usullarni chaqirish qobiliyati. Yoki kompilyatsiya vaqtida emas yoki umuman emas.
Mavjud bo'lmagan usullar haqida dostonBu qanday sodir bo'ldi? Juda oddiy - biz usulni chaqirganimizda, aslida usulni chaqiramiz
bool TryInvokeMember
(InvokeMemberBinder biriktiruvchisi, ob'ekt [] args, ob'ekt natijasi)
NonExistentMethod()
usuli chaqirilganda, bu usul argumentlarsiz chaqiriladi va bog'lovchi parametr faqat qo'ng'iroq haqida ma'lumotni o'z ichiga oladi.
{Microsoft.CSharp.RuntimeBinder.CSharpInvokeMemberBinder}
[Microsoft.CSharp.RuntimeBinder.CSharpInvokeMemberBinder]: {Microsoft.CSharp.RuntimeBinder.CSharpInvokeMemberBinder}
base {System.Dynamic.DynamicMetaObjectBinder}: {Microsoft.CSharp.RuntimeBinder.CSharpInvokeMemberBinder}
CallInfo: {System.Dynamic.CallInfo}
IgnoreCase: false
Name: "NonExistentMethod"
ReturnType: {Name = "Object" FullName = "System.Object"}
Bunday holda, biz qandaydir tarzda qayta ishlanishi mumkin bo'lgan usulning nomini olamiz. Qanday - bu sizga bog'liq. Bu erda har qanday biznes mantig'i bo'lishi mumkin. Shunga qaramay, argumentlarni qabul qilish (args) va natijani (natijani) qaytarish mexanizmlari mavjud. Agar hamma narsa muvaffaqiyatli bo'lgan bo'lsa, usul "true" yoki hamma narsa qamrab olingan bo'lsa, "noto'g'ri" ni qaytaradi. Ushbu usuldan false qiymatini qaytarish biz yuqorida ko'rgan istisnoni olib tashlaydi.
DynamicObject uchun haddan tashqari yuklangan operatsiyalar to'plami ta'sirli. Birinchidan, bu mavjud bo'lmagan xususiyatlarga kirishga, shuningdek konvertatsiyalarga, unar va ikkilik operatorlarga, indeks orqali kirishga va hokazolarga javob berish qobiliyatidir. Ba'zi amallar C#/VB uchun umuman mo'ljallanmagan - masalan, ob'ektni yaratishga xalaqit berish, ob'ekt a'zolarini o'chirish, ob'ektni indeks bo'yicha o'chirish va hokazo.
Bitta kichik hodisa bor - bu orqali siz statik ravishda kiritilgan dinamik DO o'rniga statik DO ob'ektini olasiz. Ushbu muammoning echimi oldindan taxmin qilinadi:
private dynamic This { get { return this; } }
Do'stlaringiz bilan baham: |