我有這些課程
public class SubMenuItem : SubMenuVariant
{
public string SubMenuTitle { get; set; }
public LinkFieldType Link { get; set; }
public List<SubMenuSubItem> SubItems { get; set; }
}
public class SubMenuHighlightItem : SubMenuVariant
{
[JsonPropertyName(FieldNames.HighlightTitle)]
public string HighlightTitle { get; set; }
[JsonPropertyName(FieldNames.HighlightText)]
public string HighlightText { get; set; }
[JsonPropertyName(FieldNames.HighlightText)]
public Link HighLightLink { get; set; }
}
public class SubMenuVariant
{
}
我目前存盤在List<SubMenuVariant> submenu
問題是盡管我無法訪問不同選單所具有的各個屬性,因為它們被強制轉換為沒有任何屬性的 SubMenuVariant。
串列只能包含一種型別,串列中絕不會同時存在兩種型別。這些專案并未顯式添加到串列中,而是由 JsonSerializer 創建。將包含屬性的 json 請求反序列化到基類。
所以json可以看起來像這樣:
{
"submenu": [
{
"SubMenuTitle " : "Title",
"Link" : "Link",
"SubItems" : [
{...}
]
}
]
}
或者
{
"submenu": [
{
"HighlightTitle " : "Title",
"HighlightLink" : "Link",
"HighlightText" : "Text"
}
]
}
是否可以在同一個串列中存盤不同的型別別?
uj5u.com熱心網友回復:
您的問題不在于您不能存盤從同一基類派生的不同型別。您的問題是訪問物件的運行時型別的成員。這需要演員表。當您將它們從串列中取出時,您可以有條件地投射它們:
foreach (var smv in submenu)
{
var smi = smv as SubMenuItem;
if (smi != null)
{
// ...
}
else
{
var smhi = smv as SubMenuHighlightItem;
if (smhi != null)
{
// ...
}
}
}
在較新版本的 C# 中,您可以使用模式匹配:
foreach (var smv in submenu)
{
if (smv is SubMenuItem smi)
{
// ...
}
else if (smv is SubMenuHighlightItem smhi)
{
// ...
}
}
以下是模式匹配選項的示例:
class Program
{
static void Main(string[] args)
{
var items = new List<BaseType>();
items.Add(new FirstDerivedType { FirstName = "One" });
items.Add(new SecondDerivedType { SecondName = "Two" });
items.Add(new FirstDerivedType { FirstName = "Three" });
items.Add(new SecondDerivedType { SecondName = "Four" });
foreach (var bt in items)
{
if (bt is FirstDerivedType fdt)
{
Console.WriteLine(fdt.FirstName);
}
else if (bt is SecondDerivedType sdt)
{
Console.WriteLine(sdt.SecondName);
}
}
}
}
public class FirstDerivedType : BaseType
{
public string FirstName { get; set; }
}
public class SecondDerivedType : BaseType
{
public string SecondName { get; set; }
}
public class BaseType
{
}
uj5u.com熱心網友回復:
不,您的解決方案已盡善盡美。唯一的其他更糟糕的選擇是List<object>。
uj5u.com熱心網友回復:
您也可以嘗試反射,如果您知道屬性名稱,您可以按如下方式訪問它:
internal class Program
{
static void Main(string[] args)
{
List<SubMenuVariant> variants = new List<SubMenuVariant>();
variants.Add(new Sub1() { Title = "Test" });
variants.Add(new Sub2());
var prop = variants.First().GetType().GetProperty("Title");
prop?.GetValue(variants.First(), null);
}
}
public class Sub1 :SubMenuVariant
{
public string Title { get; set; }
}
public class Sub2: SubMenuVariant
{
public int Index { get; set; }
}
public class SubMenuVariant
{
}
這將產生以下結果:

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/519733.html
上一篇:mypy和基本繼承
下一篇:為什么繼承會破壞訪問權限
