[英]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語句。如何重寫呢? 在此示例中,我需要獲取 FirstName
, LastName
, BrandName
, Name
和Email
。但是我只得到前四個屬性,除了 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.