Turpinot aizsākto tēmu par jaunās paaudzes programmēšanas valodas gaidāmo jaunāko versiju nolēmu izmēģināt spēkus dinamiskajā lauciņā. Iepriekšējā reizā aplūkojām C# valodu no dinamisku objektu patērētāja redzes punkta. Šoreiz konkrēti par dinamiskā objekta definēšanu pašu spēkiem. Pašdefinēta dinamiskā objekta ideja ir "es pats zinu kā veikt pareizi dispatch metodēm šim objektam". Šāda veida pieeja lieti noderētu, ja vēlas veidot, piemēram, dažāda veida shortcutus vai dinamiskas metodes tabulas lookup, lai veiktu korektu metodes izsaukuma dispetčera darbu.
Viss, kas mums ir nepieciešams šī mērķa realizācijai ir definēt jaunu objektu, kas realizēs IDynamicObject interfeisu. Interfeiss ir pavisam vienkārš:
namespace System.Scripting.Actions
{ public interface IDynamicObject
{ MetaObject GetMetaObject(Expression parameter);
}
}
MetaObject klase savukārt ir klase, kas zina kādā veidā ir jāreaģē uz dažādiem izsaukumiem, kas sevī ietver metodes, īpašības uzstādīšana vai vērtības saņemšana utt. Zemāk ir dots pilns MetaObject klases saturs:
public class MetaObject
{ public MetaObject(Expression expression, Restrictions restrictions);
public MetaObject(Expression expression, Restrictions restrictions, object value);
public Expression Expression { get; } public bool HasValue { get; } public bool IsByRef { get; } public bool IsDynamicObject { get; } public Type LimitType { get; } public virtual bool NeedsDeferral { get; } public Restrictions Restrictions { get; } public Type RuntimeType { get; } public object Value { get; }
public virtual MetaObject Call(CallAction action, MetaObject[] args);
public virtual MetaObject Convert(ConvertAction action, MetaObject[] args);
public virtual MetaObject Create(CreateAction action, MetaObject[] args);
public virtual MetaObject DeleteMember(DeleteMemberAction action, MetaObject[] args);
public static Expression[] GetExpressions(MetaObject[] objects);
public virtual MetaObject GetMember(GetMemberAction action, MetaObject[] args);
public virtual MetaObject Invoke(InvokeAction action, MetaObject[] args);
public virtual MetaObject Operation(OperationAction action, MetaObject[] args);
public virtual MetaObject Restrict(Type type);
public virtual MetaObject SetMember(SetMemberAction action, MetaObject[] args);
}
Lai varētu sekmīgi definēt dinamisko objektu, nepieciešams definēt jaunu klasi, kas mantosies no MetaObject klases un piedāvās "pareizo" dispitčera darbu.
public class FirstMetaObject : MetaObject
{ public FirstMetaObject(Expression parameter)
: base(parameter, Restrictions.Empty)
{ }
public override MetaObject Call(CallAction action, MetaObject[] args)
{ System.Console.WriteLine("Call of method '{0}'", action.Name); return this;
}
public override MetaObject GetMember(GetMemberAction action, MetaObject[] args)
{ System.Console.WriteLine("Call of get memeber '{0}'", action.Name); return this;
}
public override MetaObject SetMember(SetMemberAction action, MetaObject[] args)
{ System.Console.WriteLine("Call of set memeber '{0}'", action.Name); return this;
}
}
Klasē gan nav pilna nepieciešamā implementācija, bet gan tikai minimālākā, lai parādītu dinamiskā objekta ideoloģiju. Šis ir tieši tas, ko darītu teiksim IronPython implementācija.
Pēc nepieciešamās klases nodefinēšanas varam sākt rakstīt klienta kodu jaunajam objektam.
static void Main(string[] args)
{ dynamic o = new FirstDynamicObject();
o.TestProperty = "stringz";
o.TestMethodWithParameters(o.TestProperty, o.TestMethod());
}
Un izsaukumi izveidotajā objektā ir sekojoši:
Man jau šķiet "pretty cool" šāda veida fīča, kas spēj dod sistēmai sava veida dzīvību ub dinamiskumu :)
Skatoties nākotnē un reālos šīs iespējas pielietojumus, jāsecina, ka izmantot šo iespēju gan nāksies uzmanīgi, lai neradītu spēcīgus side-effectus pārējās sistēmas komponentēs.
Saistītie raksti šajā kategorijā - "Jaunais {dinamiskais} vilnis".
Cerams, ka noderēs!