/// добавление части слова
        /// wordPart - оставшася часть слова
        /// pBase - базовая форма
        unsafe private void AddWordPart(char *wordPart, BaseMorphoForm baseMorphoForm)
        {
            var first_char = *wordPart;

            if (first_char == '\0')
            /// сохранение характеристик
            {
                var tuples = from morphoForm in baseMorphoForm.MorphoForms
                             select new
                {
                    ending = morphoForm.EndingUpper,
                    baseMorphoForm,
                    morphoForm,
                };
                var dict = new Dictionary <string, LinkedList <Pair> >();
                foreach (var t in tuples)
                {
                    if (!dict.TryGetValue(t.ending, out LinkedList <Pair> pairs))
                    {
                        pairs = new LinkedList <Pair>();
                        dict.Add(t.ending, pairs);
                    }
                    pairs.AddLast(new Pair(t.baseMorphoForm, MorphoAttributePair.GetMorphoAttribute(t.baseMorphoForm, t.morphoForm)));
                }

                if (_EndingDictionary == null)
                {
                    _EndingDictionary = new Dictionary <string, Pair[]>();
                }
                foreach (var p in dict)
                {
                    if (!_EndingDictionary.TryGetValue(p.Key, out Pair[] pairs))
        /// добавление части слова
        /// wordPart - оставшася часть слова
        /// pBase - базовая форма
        unsafe private void AddWordPart(char *wordPart, BaseMorphoForm baseMorphoForm)
        {
            var first_char = *wordPart;

            if (first_char == '\0')
            /// сохранение характеристик
            {
                if (_BaseMorphoForms == null)
                {
                    _BaseMorphoForms = new List <BaseMorphoForm>();
                }
                _BaseMorphoForms.Add(baseMorphoForm);
            }
            else
            {
                TreeDictionaryClassic value;
                if (!_Slots.TryGetValue(first_char, out value))
                {
                    /// добавление новой буквы
                    value = new TreeDictionaryClassic();
                    _Slots.Add(first_char, value);
                }
                value.AddWordPart(wordPart + 1, baseMorphoForm);
            }
        }
 /// добавление слова и всех его форм в словарь
 /// word - слово
 /// pMorphoType - морфотип
 /// nounType - тип сущетсвительного
 unsafe public void AddWord(string word, MorphoType morphoType, MorphoAttributePair?nounType)
 {
     if (morphoType.MorphoForms.Length != 0)
     {
         var len            = word.Length - morphoType.MorphoForms[0].Ending.Length;
         var _base          = (0 <= len) ? word.Substring(0, len) : word;
         var baseMorphoForm = new BaseMorphoForm(_base, morphoType, nounType);
         var _baseUpper     = StringsHelper.ToUpperInvariant(_base);
         fixed(char *baseUpper_ptr = _baseUpper)
         {
             AddWordPart(baseUpper_ptr, baseMorphoForm);
         }
     }
 }
        /// получение морфологической информации по форме слова
        /// pWordFormInfo - морфологическая информация о форме слова
        /// morphologyPropertyCount [out] - количество атрибутов
        unsafe public static MorphoAttributeEnum GetMorphoAttribute(BaseMorphoForm baseMorphoForm, MorphoForm morphoForm)
        {
            var result = default(MorphoAttributeEnum);

            var morphoAttributeGroup = baseMorphoForm.MorphoAttributeGroup;

            fixed(MorphoAttributePair *map_ptr = morphoForm.MorphoAttributePairs)
            {
                for (int i = 0, len = morphoForm.MorphoAttributePairs.Length; i < len; i++)
                {
                    var morphoAttributePair = (map_ptr + i);
                    if ((morphoAttributeGroup & morphoAttributePair->MorphoAttributeGroup) == morphoAttributePair->MorphoAttributeGroup)
                    {
                        result |= morphoAttributePair->MorphoAttribute;
                    }
                    else
                    {
                        throw new WrongAttributeException();
                    }
                }
            }

            if (baseMorphoForm.NounType.HasValue)
            {
                var morphoAttributePair = baseMorphoForm.NounType.Value;
                if ((morphoAttributeGroup & morphoAttributePair.MorphoAttributeGroup) == morphoAttributePair.MorphoAttributeGroup)
                {
                    result |= morphoAttributePair.MorphoAttribute;
                }
                else
                {
                    throw new WrongAttributeException();
                }
            }

            return(result);
        }
 public Pair(BaseMorphoForm baseMorphoForm, MorphoAttributeEnum morphoAttribute)
 {
     BaseMorphoForm  = baseMorphoForm;
     MorphoAttribute = morphoAttribute;
 }