Здравствуйте, Блудов Павел, Вы писали:
БП>Гораздо проще для понимания вот такое:
БП>[Storage(ViewState), DefaultValue(0)] public PageNo : int { get; private set;}
БП>Тут совершенно ясно, что происходит и лушние детали в глаза не лезут.
Это какйо-то странный синтаксис. У тебя проблема предметной области, ну, и нечего придумывать универсальное решение. Сделай макрос ViewState с параметром defaultValue. В нем и добавишь все что тебе нужно. Выгдядеть будет так:
[ViewState(0)] public PageNo : int { get; private set; }
Автосвойства тут вообще не причем. Макрос все должен делать сам.
В общем, потратил 20 минут наклепал этот макрос:
using Nemerle;
using Nemerle.Compiler;
using Nemerle.Collections;
using Nemerle.Utility;
using Nemerle.Compiler.Parsetree;
using System;
namespace MacroLibrary2
{
[MacroUsage(MacroPhase.BeforeTypedMembers, MacroTargets.Property, Inherited = true)]
macro ViewState(_ : TypeBuilder, propertyAst : ParsedProperty, defaulteValue)
{
when (!(propertyAst.Attributes %&& (NemerleAttributes.Abstract | NemerleAttributes.Extern)))
match (propertyAst.get, propertyAst.set)
{
| (Some(PT.ClassMember.Function(_, _, FunBody.Abstract) as getr),
Some(PT.ClassMember.Function(_, _, FunBody.Abstract) as setr)) =>
def ctx = Nemerle.Macros.ImplicitCTX();
ctx.Env.Manager.MacroColors.PushUseSiteColor();
try
{
getr.Body = <[
def val = $("ViewState" : usesite)[$(propertyAst.Name : string)];
if (val == null) $defaulteValue else (val :> $(propertyAst.ty))
]>;
setr.Body = <[ $("ViewState" : usesite)[$(propertyAst.Name : string)] = value ]>;
}
finally { ctx.Env.Manager.MacroColors.PopColor(); }
| _ => Message.Error(propertyAst.Location, "Property should have empty getter and setter!")
}
}
}
Использование:
using System;
using Nemerle.Collections;
using System.Console;
using Nemerle.Utility;
using MacroLibrary2;
public class A
{
ViewState : System.Collections.Hashtable = System.Collections.Hashtable();
[ViewState(0)]
public Prop1 : int { get; set; }
[ViewState("<empty>")]
public Prop2 : string { get; set; }
}
module Program
{
Main() : void
{
def a = A();
WriteLine($"a.Prop1=$(a.Prop1)");
WriteLine($"a.Prop2=$(a.Prop2)");
a.Prop1 = 123;
a.Prop2 = "test";
WriteLine($"a.Prop1=$(a.Prop1)");
WriteLine($"a.Prop2=$(a.Prop2)");
Write("..."); _ = ReadLine();
}
}
Вывод:
a.Prop1=0
a.Prop2=<empty>
a.Prop1=123
a.Prop2=test
ЗЫ
Что касается 20 минут. Перед этим конечно пару месяцев нужно потратить на исследование макросистемы, а лушче еще годик на изучение компилятора. Тогда за 20 минут легко такие вещи делаются.
Без этих знаний конечно будет не просто. Но думаю, что после того как я допишу цикл статей по макросам — это будет доступно всем кто умеет читать по русски.
... << RSDN@Home 1.2.0 alpha rev. 637>>