получается в некоторых местах подобный код. он меня не радует, потому что мог бы быть покороче/пояснее.
например объединить циклы не получается, от true/false рябит в глазах.
def isPrimitiveValue(ty) //ty : TypeInfo
/*проверяет ty на то, примитивный он value или состоит только из примитивных value*/if (ty.IsValueType)
if (ty.IsPrimitive)
true
else
def parse_type = man.NameTree.NamespaceTree.LookupType([ty.ToString()], 1)
if (parse_type.HasValue)
foreach(member is ClassMember.Field in (parse_type.Value :> TypeBuilder).GetParsedMembers())
when (!isPrimitiveValue(typer.BindFixedType(member.ty)))
return false
else
foreach(member is ClassMember.Field in ty.TypeInfo.GetMembers())
when (!isPrimitiveValue(typer.BindFixedType(member.ty)))
return false
true
else
false
так вроде лучше, но еще чего-то не хватает с циклами..
def testType(ty, predicate)
def parse_type = man.NameTree.NamespaceTree.LookupType([ty.ToString()], 1)
if (parse_type.HasValue)
foreach(member is ClassMember.Field in (parse_type.Value :> TypeBuilder).GetParsedMembers())
when (!predicate(typer.BindFixedType(member.ty)))
return false
else
foreach(member is ClassMember.Field in ty.TypeInfo.GetMembers())
when (!predicate(typer.BindFixedType(member.ty)))
return false
true
def isPrimitiveValue(ty) //ty : TypeInfo
/*проверяет ty на то, примитивный он value или состоит только из примитивных value*/if (ty.IsValueType)
if (ty.IsPrimitive)
true
else
testType(ty, isPrimitiveValue)
else
false
Re[2]: код выглядит несколько дебильно. что делать?
Здравствуйте, _Claus_, Вы писали:
_C_>так вроде лучше, но еще чего-то не хватает с циклами..
_C_>
_C_> def testType(ty, predicate)
_C_> def parse_type = man.NameTree.NamespaceTree.LookupType([ty.ToString()], 1)
_C_> if (parse_type.HasValue)
_C_> foreach(member is ClassMember.Field in (parse_type.Value :> TypeBuilder).GetParsedMembers())
_C_> when (!predicate(typer.BindFixedType(member.ty)))
_C_> return false
_C_> else
_C_> foreach(member is ClassMember.Field in ty.TypeInfo.GetMembers())
_C_> when (!predicate(typer.BindFixedType(member.ty)))
_C_> return false
_C_> true
_C_> def isPrimitiveValue(ty) //ty : TypeInfo
_C_> /*проверяет ty на то, примитивный он value или состоит только из примитивных value*/
_C_> if (ty.IsValueType)
_C_> if (ty.IsPrimitive)
_C_> true
_C_> else
_C_> testType(ty, isPrimitiveValue)
_C_> else
_C_> false
_C_>
А если переписать isPrimitiveValue вот так? (я даже не пробовал компилировать)
def isPrimitiveValue(ty) //ty : TypeInfo
{
/*проверяет ty на то, примитивный он value или состоит только из примитивных value*/match (ty.IsValueType, ty.IsPrimitive)
{
| (true, true) => true
| (true, false) => testType(ty, isPrimitiveValue)
| (false, _) => false
}
}
Mumitroller
... << RSDN@Home 1.2.0 alpha 4 rev. 0>>
Re[2]: код выглядит несколько дебильно. что делать?
Здравствуйте, _Claus_, Вы писали:
_C_>так вроде лучше, но еще чего-то не хватает с циклами..
_C_>
_C_> def testType(ty, predicate)
_C_> def parse_type = man.NameTree.NamespaceTree.LookupType([ty.ToString()], 1)
_C_> if (parse_type.HasValue)
_C_> foreach(member is ClassMember.Field in (parse_type.Value :> TypeBuilder).GetParsedMembers())
_C_> when (!predicate(typer.BindFixedType(member.ty)))
_C_> return false
_C_> else
_C_> foreach(member is ClassMember.Field in ty.TypeInfo.GetMembers())
_C_> when (!predicate(typer.BindFixedType(member.ty)))
_C_> return false
_C_> true
_C_> def isPrimitiveValue(ty) //ty : TypeInfo
_C_> /*проверяет ty на то, примитивный он value или состоит только из примитивных value*/
_C_> if (ty.IsValueType)
_C_> if (ty.IsPrimitive)
_C_> true
_C_> else
_C_> testType(ty, isPrimitiveValue)
_C_> else
_C_> false
_C_>
можно как то так, исправь если я где то что ошибся:
def isPrimitiveValue(ty : TypeInfo) //ty : TypeInfo
{
def is_field_primitive(f)
{
| ClassMember.Field(ty = t) => !isPrimitiveValue(typer.BindFixedType(t))
| _ => false
}
/*проверяет ty на то, примитивный он value или состоит только из примитивных value*/match (ty)
{
| _ when !ty.IsValueType => false
| _ when ty.IsPrimitive => true
| _ => def mems = match (man.NameTree.NamespaceTree.LookupType([ty.ToString()], 1))
{
| Some(t) => (parse_type.Value :> TypeBuilder).GetParsedMembers()
| _ => ty.TypeInfo.GetMembers()
}
!mems.Exists(is_field_primitive)
}
}
Re[2]: код выглядит несколько дебильно. что делать?
Здравствуйте, _Claus_, Вы писали:
_C_>так вроде лучше, но еще чего-то не хватает с циклами..
_C_>
_C_> def testType(ty, predicate)
_C_> def parse_type = man.NameTree.NamespaceTree.LookupType([ty.ToString()], 1)
_C_> if (parse_type.HasValue)
_C_> foreach(member is ClassMember.Field in (parse_type.Value :> TypeBuilder).GetParsedMembers())
_C_> when (!predicate(typer.BindFixedType(member.ty)))
_C_> return false
_C_> else
_C_> foreach(member is ClassMember.Field in ty.TypeInfo.GetMembers())
_C_> when (!predicate(typer.BindFixedType(member.ty)))
_C_> return false
_C_> true
_C_> def isPrimitiveValue(ty) //ty : TypeInfo
_C_> /*проверяет ty на то, примитивный он value или состоит только из примитивных value*/
_C_> if (ty.IsValueType)
_C_> if (ty.IsPrimitive)
_C_> true
_C_> else
_C_> testType(ty, isPrimitiveValue)
_C_> else
_C_> false
_C_>
в топку return, используй функциональный стиль, горы if можно заменить на match с when противоположных условий как я показал
Re[3]: код выглядит несколько дебильно. что делать?
Здравствуйте, catbert, Вы писали:
C>Здравствуйте, _Claus_, Вы писали:
_C_>>так вроде лучше, но еще чего-то не хватает с циклами..
C>Попробуйте Exists и ForAll
да все равно два почти одинаковых фрагмента и кода не меньше..
как то в один ужаться бы
Re[3]: код выглядит несколько дебильно. что делать?
_C_>это почти что надо. проблема осталась — компилятор не желает тип для mems выводить, грит — IMember это вообще не ClassMember.
_C_>def mems = match (man.NameTree.NamespaceTree.LookupType([ty.ToString()], 1)) _C_> | Some(t) => (t :> TypeBuilder).GetParsedMembers() _C_> | _ => ty.GetMembers()
_C_>если убедим, будет хорошо.
я боюсь здесь ошибиться с выводами типов:
def isPrimitiveValue(ty : TypeInfo) //ty : TypeInfo
{
def get_fields_type(f, a)
{
match (f)
{
| ClassMember.Field(ty = t) => typer.BindFixedType(t) :: a
| _ => a
}
}
/*проверяет ty на то, примитивный он value или состоит только из примитивных value*/match (ty)
{
| _ when !ty.IsValueType => false
| _ when ty.IsPrimitive => true
| _ => def mems = match (man.NameTree.NamespaceTree.LookupType([ty.ToString()], 1))
{
// кстати здесь не используется значение Some в твоем коде я не могу понять как ты хотел его использовать
| Some => def mems = (parse_type.Value :> TypeBuilder).GetParsedMembers();
mems.FoldLeft([], get_fields_type)
| _ => def mems = ty.GetMembers();
mems.Map(_.GetMemType());
}
!mems.Exists(_.IsPrimitive)
}
}
но основная идея такова, здесь из за несоответствия я все привел к FixedType и получил его флаг IsPrimitive, не проверял сработает ли это в твоей задаче, может кто нибудь из более продвинутых в выводе типов, подскажет.
PS: FoldLeft здесь выполняет функцию накопления, только для полей
Здравствуйте, _Claus_, Вы писали:
_C_> получается в некоторых местах подобный код. он меня не радует, потому что мог бы быть покороче/пояснее. _C_> например объединить циклы не получается, от true/false рябит в глазах. _C_>
_C_> def isPrimitiveValue(ty) //ty : TypeInfo
_C_> /*проверяет ty на то, примитивный он value или состоит только из примитивных value*/
_C_> if (ty.IsValueType)
_C_> if (ty.IsPrimitive)
_C_> true
_C_> else
_C_> def parse_type = man.NameTree.NamespaceTree.LookupType([ty.ToString()], 1)
_C_> if (parse_type.HasValue)
_C_> foreach(member is ClassMember.Field in (parse_type.Value :> TypeBuilder).GetParsedMembers())
_C_> when (!isPrimitiveValue(typer.BindFixedType(member.ty)))
_C_> return false
_C_> else
_C_> foreach(member is ClassMember.Field in ty.TypeInfo.GetMembers())
_C_> when (!isPrimitiveValue(typer.BindFixedType(member.ty)))
_C_> return false
_C_> true
_C_> else
_C_> false
_C_>
ну по идее должно работать что то типа такого (интеграции не стоит, поэтому компилябельность под вопросом)
match (ty.IsValueType, ty.IsPrimitive)
{
| (true, true) => true;
| (true, false) =>
match (man.NameTree.NamespaceTree.LookupType([ty.ToString()], 1))
{
| Some(parsed_ty) with mems = (parsed_ty :> TypeBuilder).GetParsedMembers()
| None with mems = ty.TypeInfo.GetMembers() =>
mems.OfType.[ClassMember.Field]().All(isPrimitiveValue(typer.BindFixedType(_.ty)));
}
| (false, _) => false;
}
Re[5]: код выглядит несколько дебильно. что делать?
Здравствуйте, CodingUnit, Вы писали:
CU>Здравствуйте, _Claus_, Вы писали:
Помоему можно даже так, только там надо указать правильно флаги какие поля берем:
def isPrimitiveValue(ty : TypeInfo) //ty : TypeInfo
{
/*проверяет ty на то, примитивный он value или состоит только из примитивных value*/match (ty)
{
| _ when !ty.IsValueType => false
| _ when ty.IsPrimitive => true
| _ => def mems = match (man.NameTree.NamespaceTree.LookupType([ty.ToString()], 1))
{
| Some => (parse_type.Value :> TypeBuilder).GetFields();
| _ => ty.GetFields(BindingFlags.Default)
}
!mems.Exists(x => x.GetMemType().IsPrimitive)
}
}
Re[6]: код выглядит несколько дебильно. что делать?
_C_>не переваривает, тип mems не выводит. а так был бы the best.
_C_>я вот так привести воедино, чтобы таки влить в одну дырку, а оно не желает, почему — непонятно!
_C_>ty.GetMembers().Filter(x => x is ClassMember).Map(_ :> ClassMember)
_C_>грит не тот тип у предиката фильтра, похоже на баг.
Это не баг, все правильно говорит посмотри какие типы на выходе GetParsedMembers() и GetMembers() у одного list[ClassMember] у другого list[IMember], они никак не пересекаеются, это два разных дерева парсинга и типизированное, надо их объеденять концептуально, то есть получить из них что мы хотим и использовать вовне, примерно как я делал. Посмотри что ты можешь взять из ClassMember и IMember помоему там достаточно информации, вообщем повозись, ответ на поверхности, ошибка выеденного яйца не стоит.
Здравствуйте, _Claus_, Вы писали:
_C_> получается в некоторых местах подобный код. он меня не радует, потому что мог бы быть покороче/пояснее. _C_> например объединить циклы не получается, от true/false рябит в глазах.
1. Как я понял в ty находится FixedType. Надо был это явно показать, чтобы не надо было домысливать.
Ты получаешь тоже самое значение что и было в ty.TypeInfo. Нужно было сделать:
match (ty.TypeInfo)
{
| t is TypeBuilder => ...
| _ => ...
}
3. Этот код был бы проще, если бы он работал на стадии WithTypedMember. Тогда ty.TypeInfo.GetMembers() давал бы список членов в обоих случаях и их не пришлось бы разделять.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: код выглядит несколько дебильно. что делать?
Здравствуйте, Jack128, Вы писали:
J>Здравствуйте, _Claus_, Вы писали:
_C_>>не переваривает, тип mems не выводит. а так был бы the best.
J>ну если, как говорит CodingUnit, там типы list[ClassMember] и list[IMember] то можно попробывать написать так:
J>
J>| Some(parsed_ty) with mems = (parsed_ty :> TypeBuilder).GetParsedMembers() : IEnumerable.[_]
J>| None with mems = ty.TypeInfo.GetMembers() : IEnumerable.[_] =>
J>
J>и посмотреть выведет ли N типы из ковариантного IEnumerable[_] (если у тя .NET4 компилер)
J>Если не получится, то придется в ран тайм проверку переносить: J>
J>| Some(parsed_ty) with mems = (parsed_ty :> TypeBuilder).GetParsedMembers().Cast.[IMember]
J>| None with mems = ty.TypeInfo.GetMembers().Cast.[IMember] =>
J>
Не запутывай товарища, ClassMember ни во время компиляции, ни во время рантайма никак не приведется к IMember, поскольку они не связаны, это два разных дерева, подходить надо по другому. Может там эта вся мишура и ненужна, если послушать Влада и сделать на фазе WithTypedMembers, как он говорит.
Re[5]: код выглядит несколько дебильно. что делать?
Здравствуйте, CodingUnit, Вы писали:
CU>Не запутывай товарища, ClassMember ни во время компиляции, ни во время рантайма никак не приведется к IMember, поскольку они не связаны, это два разных дерева
А, прошу прощения, не знал. Ориентировался чисто по названию классов/интерфейсов.
Re[6]: код выглядит несколько дебильно. что делать?
Здравствуйте, Jack128, Вы писали:
J>Здравствуйте, CodingUnit, Вы писали:
CU>>Не запутывай товарища, ClassMember ни во время компиляции, ни во время рантайма никак не приведется к IMember, поскольку они не связаны, это два разных дерева
J>А, прошу прощения, не знал. Ориентировался чисто по названию классов/интерфейсов.
Ничего, бывает, но лучше перед ответом протестить код, благо NPad всегда под рукой, или VS.
Re[2]: код выглядит несколько дебильно. что делать?
VD>3. Этот код был бы проще, если бы он работал на стадии WithTypedMember. Тогда ty.TypeInfo.GetMembers() давал бы список членов в обоих случаях и их не пришлось бы разделять.