код выглядит несколько дебильно. что делать?
От: _Claus_  
Дата: 14.12.11 16:40
Оценка:
получается в некоторых местах подобный код. он меня не радует, потому что мог бы быть покороче/пояснее.
например объединить циклы не получается, от 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
Re: код выглядит несколько дебильно. что делать?
От: _Claus_  
Дата: 14.12.11 17:06
Оценка:
так вроде лучше, но еще чего-то не хватает с циклами..


      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]: код выглядит несколько дебильно. что делать?
От: Mumitroller Беларусь  
Дата: 14.12.11 17:14
Оценка: 1 (1)
Здравствуйте, _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]: код выглядит несколько дебильно. что делать?
От: catbert  
Дата: 14.12.11 17:14
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>так вроде лучше, но еще чего-то не хватает с циклами..


Попробуйте Exists и ForAll
Re[2]: код выглядит несколько дебильно. что делать?
От: CodingUnit Россия  
Дата: 14.12.11 17:18
Оценка:
Здравствуйте, _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]: код выглядит несколько дебильно. что делать?
От: CodingUnit Россия  
Дата: 14.12.11 17:20
Оценка:
Здравствуйте, _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]: код выглядит несколько дебильно. что делать?
От: _Claus_  
Дата: 14.12.11 17:26
Оценка:
Здравствуйте, catbert, Вы писали:

C>Здравствуйте, _Claus_, Вы писали:


_C_>>так вроде лучше, но еще чего-то не хватает с циклами..


C>Попробуйте Exists и ForAll


да все равно два почти одинаковых фрагмента и кода не меньше..
как то в один ужаться бы
Re[3]: код выглядит несколько дебильно. что делать?
От: _Claus_  
Дата: 14.12.11 17:42
Оценка:
CU>
CU>    def isPrimitiveValue(ty : TypeInfo) //ty : TypeInfo
CU>    {

CU>      def is_field_primitive(f)
CU>      {
CU>        | ClassMember.Field(ty = t) => !isPrimitiveValue(typer.BindFixedType(t))
CU>        | _                         => false
CU>      }

CU>      /*проверяет ty на то, примитивный он value или состоит только из примитивных value*/
CU>        match (ty)
CU>        {
CU>          | _ when !ty.IsValueType => false
CU>          | _ when ty.IsPrimitive => true
CU>          | _ => def mems = match (man.NameTree.NamespaceTree.LookupType([ty.ToString()], 1))
CU>                             {
CU>                               | Some(t) =>  (parse_type.Value :> TypeBuilder).GetParsedMembers()
CU>                               | _       => ty.TypeInfo.GetMembers()
CU>                             }

CU>               !mems.Exists(is_field_primitive)
CU>        }
CU>    }

CU>


это почти что надо. проблема осталась — компилятор не желает тип для mems выводить, грит — IMember это вообще не ClassMember.

def mems = match (man.NameTree.NamespaceTree.LookupType([ty.ToString()], 1))
| Some(t) => (t :> TypeBuilder).GetParsedMembers()
| _ => ty.GetMembers()

если убедим, будет хорошо.
Re[4]: код выглядит несколько дебильно. что делать?
От: CodingUnit Россия  
Дата: 14.12.11 18:07
Оценка:
Здравствуйте, _Claus_, Вы писали:


_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 здесь выполняет функцию накопления, только для полей
Re: код выглядит несколько дебильно. что делать?
От: Jack128  
Дата: 14.12.11 18:11
Оценка: 1 (1)
Здравствуйте, _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 Россия  
Дата: 14.12.11 18:16
Оценка:
Здравствуйте, 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]: код выглядит несколько дебильно. что делать?
От: CodingUnit Россия  
Дата: 14.12.11 18:18
Оценка:
Здравствуйте, CodingUnit, Вы писали:

И еще если ты хочешь получить рекурсивное поведение для всех вложенных объектов то это надо делать по другому. Но примерно так же как я начал.
Re[2]: код выглядит несколько дебильно. что делать?
От: _Claus_  
Дата: 14.12.11 19:15
Оценка:
J>ну по идее должно работать что то типа такого (интеграции не стоит, поэтому компилябельность под вопросом)
J>
J>        match (ty.IsValueType, ty.IsPrimitive)
J>        {
J>            | (true, true) => true;
J>            | (true, false) => 
J>                match (man.NameTree.NamespaceTree.LookupType([ty.ToString()], 1))
J>                {
J>                    | Some(parsed_ty) with mems = (parsed_ty :> TypeBuilder).GetParsedMembers()
J>                    | None            with mems = ty.TypeInfo.GetMembers() =>
J>                         mems.OfType.[ClassMember.Field]().All(isPrimitiveValue(typer.BindFixedType(_.ty)));
J>                }
J>            | (false, _) => false;                
J>        }
J>


не переваривает, тип mems не выводит. а так был бы the best.

я вот так привести воедино, чтобы таки влить в одну дырку, а оно не желает, почему — непонятно!

ty.GetMembers().Filter(x => x is ClassMember).Map(_ :> ClassMember)

грит не тот тип у предиката фильтра, похоже на баг.
Re[3]: код выглядит несколько дебильно. что делать?
От: CodingUnit Россия  
Дата: 14.12.11 19:25
Оценка: +1
Здравствуйте, _Claus_, Вы писали:

J>>ну по идее должно работать что то типа такого (интеграции не стоит, поэтому компилябельность под вопросом)

J>>
J>>        match (ty.IsValueType, ty.IsPrimitive)
J>>        {
J>>            | (true, true) => true;
J>>            | (true, false) => 
J>>                match (man.NameTree.NamespaceTree.LookupType([ty.ToString()], 1))
J>>                {
J>>                    | Some(parsed_ty) with mems = (parsed_ty :> TypeBuilder).GetParsedMembers()
J>>                    | None            with mems = ty.TypeInfo.GetMembers() =>
J>>                         mems.OfType.[ClassMember.Field]().All(isPrimitiveValue(typer.BindFixedType(_.ty)));
J>>                }
J>>            | (false, _) => false;                
J>>        }
J>>


_C_>не переваривает, тип mems не выводит. а так был бы the best.


_C_>я вот так привести воедино, чтобы таки влить в одну дырку, а оно не желает, почему — непонятно!


_C_>ty.GetMembers().Filter(x => x is ClassMember).Map(_ :> ClassMember)


_C_>грит не тот тип у предиката фильтра, похоже на баг.


Это не баг, все правильно говорит посмотри какие типы на выходе GetParsedMembers() и GetMembers() у одного list[ClassMember] у другого list[IMember], они никак не пересекаеются, это два разных дерева парсинга и типизированное, надо их объеденять концептуально, то есть получить из них что мы хотим и использовать вовне, примерно как я делал. Посмотри что ты можешь взять из ClassMember и IMember помоему там достаточно информации, вообщем повозись, ответ на поверхности, ошибка выеденного яйца не стоит.
Re: код выглядит несколько дебильно. что делать?
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.12.11 19:34
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_> получается в некоторых местах подобный код. он меня не радует, потому что мог бы быть покороче/пояснее.

_C_> например объединить циклы не получается, от true/false рябит в глазах.

1. Как я понял в ty находится FixedType. Надо был это явно показать, чтобы не надо было домысливать.

2. Вот это:
_C_>
_C_>            def parse_type = man.NameTree.NamespaceTree.LookupType([ty.ToString()], 1)
_C_>

это какой-то полный "П".

Ты получаешь тоже самое значение что и было в ty.TypeInfo. Нужно было сделать:
match (ty.TypeInfo)
{
  | t is TypeBuilder => ...
  | _ => ...
}


3. Этот код был бы проще, если бы он работал на стадии WithTypedMember. Тогда ty.TypeInfo.GetMembers() давал бы список членов в обоих случаях и их не пришлось бы разделять.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: код выглядит несколько дебильно. что делать?
От: Jack128  
Дата: 14.12.11 19:35
Оценка:
Здравствуйте, _Claus_, Вы писали:


_C_>не переваривает, тип mems не выводит. а так был бы the best.


ну если, как говорит CodingUnit, там типы list[ClassMember] и list[IMember] то можно попробывать написать так:

| Some(parsed_ty) with mems = (parsed_ty :> TypeBuilder).GetParsedMembers() : IEnumerable.[_]
| None            with mems = ty.TypeInfo.GetMembers() : IEnumerable.[_] =>

и посмотреть выведет ли N типы из ковариантного IEnumerable[_] (если у тя .NET4 компилер)

Если не получится, то придется в ран тайм проверку переносить:
| Some(parsed_ty) with mems = (parsed_ty :> TypeBuilder).GetParsedMembers().Cast.[IMember]
| None            with mems = ty.TypeInfo.GetMembers().Cast.[IMember] =>
Re[4]: код выглядит несколько дебильно. что делать?
От: CodingUnit Россия  
Дата: 14.12.11 19:48
Оценка:
Здравствуйте, 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]: код выглядит несколько дебильно. что делать?
От: Jack128  
Дата: 14.12.11 20:07
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>Не запутывай товарища, ClassMember ни во время компиляции, ни во время рантайма никак не приведется к IMember, поскольку они не связаны, это два разных дерева


А, прошу прощения, не знал. Ориентировался чисто по названию классов/интерфейсов.
Re[6]: код выглядит несколько дебильно. что делать?
От: CodingUnit Россия  
Дата: 14.12.11 20:10
Оценка:
Здравствуйте, Jack128, Вы писали:

J>Здравствуйте, CodingUnit, Вы писали:


CU>>Не запутывай товарища, ClassMember ни во время компиляции, ни во время рантайма никак не приведется к IMember, поскольку они не связаны, это два разных дерева


J>А, прошу прощения, не знал. Ориентировался чисто по названию классов/интерфейсов.


Ничего, бывает, но лучше перед ответом протестить код, благо NPad всегда под рукой, или VS.
Re[2]: код выглядит несколько дебильно. что делать?
От: _Claus_  
Дата: 14.12.11 20:50
Оценка:
VD>3. Этот код был бы проще, если бы он работал на стадии WithTypedMember. Тогда ty.TypeInfo.GetMembers() давал бы список членов в обоих случаях и их не пришлось бы разделять.

мне важно на предыдущем этапе, поэтому и мыкаюсь.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.