簡體   English   中英

遞歸函數無法在C#中獲得預期的結果

[英]recursive function fails to get the expected result in c#

我有以下課程,

用戶:

public class User:Domain
    {
        [Sortable]
        public string FirstName { get; set; }

        [Sortable]
        public string LastName { get; set; }

        [NestedSortable]
        public Profile Profile { get; set; }
    }

輪廓:

public class Profile : Domain
    {
        [Sortable]
        public string BrandName { get; set; }

        [NestedSortable]
        public Client Client { get; set; }

        [NestedSortable]
        public ProfileContact ProfileContact { get; set; }
    }

客戶:

public class Client : Domain
    {
        [Sortable]
        public string Name { get; set; }
    }

個人資料聯系人:

public class ProfileContact : Domain
    {
        [Sortable]
        public string Email { get; set; }
    }

我正在編寫一個遞歸函數,以獲取所有裝飾有[Sortable]屬性的屬性。 當我只有一個[NestedSortableProperty]時,此方法效果很好,但當我有多個[NestedSortableProperty] ,此方法將失敗。

這是我的遞歸函數:

private static IEnumerable<SortTerm> GetTermsFromModel(
            Type parentSortClass,
            List<SortTerm> sortTerms,
            string parentsName = null,
            bool hasNavigation = false)
        {
            if (sortTerms is null)
            {
                sortTerms = new List<SortTerm>();
            }

            sortTerms.AddRange(parentSortClass.GetTypeInfo()
                       .DeclaredProperties
                       .Where(p => p.GetCustomAttributes<SortableAttribute>().Any())
                       .Select(p => new SortTerm
                       {
                           ParentName = parentSortClass.Name,
                           Name = hasNavigation ? $"{parentsName}.{p.Name}" : p.Name,
                           EntityName = p.GetCustomAttribute<SortableAttribute>().EntityProperty,
                           Default = p.GetCustomAttribute<SortableAttribute>().Default,
                           HasNavigation = hasNavigation
                       }));

            var complexSortProperties = parentSortClass.GetTypeInfo()
                       .DeclaredProperties
                       .Where(p => p.GetCustomAttributes<NestedSortableAttribute>().Any());

            if (complexSortProperties.Any())
            {
                foreach (var parentProperty in complexSortProperties)
                {
                    var parentType = parentProperty.PropertyType;

                    if (string.IsNullOrWhiteSpace(parentsName))
                    {
                        parentsName = parentType.Name;
                    }
                    else
                    {
                        parentsName += $".{parentType.Name}";
                    }

                    return GetTermsFromModel(parentType, sortTerms, parentsName, true);
                }
            }

            return sortTerms;
        }

發生這種情況是因為在foreach循環中有return語句。 如何重寫呢? 在此示例中,我需要獲取FirstNameLastNameBrandNameNameEmail 但是我只得到前四個屬性,除了Email

現在,通過刪除以下我自己的答案中發布的return語句並遵循@Dialecticus注釋以使用yield return可以解決上述問題。 所以我點擊並更新了問題。

現在我遇到另一個問題。 如果一個類具有多個[NestedSortable]屬性,則會錯誤地分配父類名稱。

第一次使用User類調用此方法,例如var declaredTerms = GetTermsFromModel(typeof(User), null);

例,

第一次調用后, parentsName參數將為null,並且User類中的[Sortable]屬性無效。

現在,對於User類中的[NestedSortable] Profile屬性, parentsName將是Profile ,因此Profile類中的[Sortable]屬性將Name作為Profile.BrandName ,依此類推。

最終列表中的Name屬性如下所示,

預期產量:

名字,姓氏,Profile.BrandName,Profile.Client.Name,Profile.ProfileContact.Email

但是實際輸出:

名字,姓氏,Profile.BrandName,Profile.Client.Name,Profile.Client.ProfileContact.Email

請協助解決此問題。

謝謝,

阿卜杜勒

經過一些調試后,我在foreach循環中刪除了return語句,並修復了第一個問題。

return GetTermsFromModel(parentType, sortTerms, parentsName, true);

至,

GetTermsFromModel(parentType, sortTerms, parentsName, true);

然后按照@Dialecticus注釋,刪除傳遞sortTerms作為輸入參數,並刪除代碼內部的參數,並將sortTerms.AddRange(...)更改為yield return

sortTerms.AddRange(parentSortClass.GetTypeInfo()
                       .DeclaredProperties
                       .Where(p => p.GetCustomAttributes<SortableAttribute>().Any())
                       .Select(p => new SortTerm
                       {
                           ParentName = parentSortClass.Name,
                           Name = hasNavigation ? $"{parentsName}.{p.Name}" : p.Name,
                           EntityName = p.GetCustomAttribute<SortableAttribute>().EntityProperty,
                           Default = p.GetCustomAttribute<SortableAttribute>().Default,
                           HasNavigation = hasNavigation
                       }));

至,

foreach (var p in properties)
            {
                yield return new SortTerm
                {
                    ParentName = parentSortClass.Name,
                    Name = hasNavigation ? $"{parentsName}.{p.Name}" : p.Name,
                    EntityName = p.GetCustomAttribute<SortableAttribute>().EntityProperty,
                    Default = p.GetCustomAttribute<SortableAttribute>().Default,
                    HasNavigation = hasNavigation
                };
            }

對於復雜的屬性,從

GetTermsFromModel(parentType, sortTerms, parentsName, true);

至,

var complexProperties = GetTermsFromModel(parentType, parentsName, true);

                    foreach (var complexProperty in complexProperties)
                    {
                        yield return complexProperty;
                    }

對於最后一個問題,我遇到了這個名稱,在內部foreach循環修復它之后添加以下代碼,

parentsName = parentsName.Replace($".{parentType.Name}", string.Empty);

因此,這是完整的更新后的工作代碼:

private static IEnumerable<SortTerm> GetTermsFromModel(
            Type parentSortClass,
            string parentsName = null,
            bool hasNavigation = false)
        {
            var properties = parentSortClass.GetTypeInfo()
                       .DeclaredProperties
                       .Where(p => p.GetCustomAttributes<SortableAttribute>().Any());

            foreach (var p in properties)
            {
                yield return new SortTerm
                {
                    ParentName = parentSortClass.Name,
                    Name = hasNavigation ? $"{parentsName}.{p.Name}" : p.Name,
                    EntityName = p.GetCustomAttribute<SortableAttribute>().EntityProperty,
                    Default = p.GetCustomAttribute<SortableAttribute>().Default,
                    HasNavigation = hasNavigation
                };
            }

            var complexSortProperties = parentSortClass.GetTypeInfo()
                       .DeclaredProperties
                       .Where(p => p.GetCustomAttributes<NestedSortableAttribute>().Any());

            if (complexSortProperties.Any())
            {
                foreach (var parentProperty in complexSortProperties)
                {
                    var parentType = parentProperty.PropertyType;

                    //if (string.IsNullOrWhiteSpace(parentsName))
                    //{
                    //    parentsName = parentType.Name;
                    //}
                    //else
                    //{
                    //    parentsName += $".{parentType.Name}";
                    //}

                    var complexProperties = GetTermsFromModel(parentType, string.IsNullOrWhiteSpace(parentsName) ? parentType.Name : $"{parentsName}.{parentType.Name}", true);

                    foreach (var complexProperty in complexProperties)
                    {
                        yield return complexProperty;
                    }

                    //parentsName = parentsName.Replace($".{parentType.Name}", string.Empty);
                }
            }
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM