我正在把頭發拉出來。看起來很簡單,但事實并非如此。我只想創建一個簡單的設定串列。每個設定都有一個“名稱”、“值”和“默認值”。每個設定的“值”/“默認值”可以是任何簡單型別(bool、int、float、string 等)。
似乎串列需要是可迭代的,因此我可以實作讀/寫函式來保存設定并稍后加載它們,或者按名稱搜索設定以確定它是否存在,回傳其值等。
這是我嘗試過的(在許多其他事情中):
abstract class BaseSetting
{
public string Name { get; set; }
}
class Setting<T> : BaseSetting
{
public Setting(string name, T value, T def) { Name = name; Value = value; DefaultValue = def; }
public T Value { get; set; }
public T DefaultValue { get; set; }
}
// Create iterable list of settings:
List<BaseSetting> Settings = new List<BaseSetting>(); // Have to use the Base class so the list will accept subclasses with various types.
// Add subclasses of various types to the list:
Settings.Add(new Setting<int>("IntSetting", 123, 456));
Settings.Add(new Setting<bool>("BoolSetting", true, false));
Settings.Add(new Setting<double>("FloatSetting", 3.14, 2.718));
// Iterate settings to do something (i.e. save all settings to a file)
foreach(var s in Settings)
{
Console.WriteLine("Name of setting: " s.Name);
Console.WriteLine("Value of setting: " s.Value.ToString()); // ERROR: no member named "Value"
}
(見小提琴:https ://dotnetfiddle.net/F4x2Di )
在嘗試迭代設定時,我無法訪問 Value 或 DefaultValue 屬性,因為它們不存在于基類中,并且我無法嘗試將基類轉換為子類,因為我無法訪問Value/DefaultValue 屬性以獲取它們的型別以傳遞給強制轉換。
我還認為我可以在基類中為 Value 和 DefaultValue 添加一個通用的“物件”屬性,然后在子類中用所需的型別覆寫它,但這也是不允許的:不能在覆寫中更改型別。
我剩下的頭發會非常感謝這一個的指導。有沒有辦法在可迭代串列中用泛型型別實作這樣的類?還是這是解決手頭問題的錯誤方法?
uj5u.com熱心網友回復:
嗯,這是一個不錯的。如果您要在基類中訪問它,則它可能具有的唯一型別是物件(除非您限制 T)
所以:https ://dotnetfiddle.net/lHE1gv
using System;
using System.Collections.Generic;
abstract class BaseSetting
{
protected abstract object GetValue();
public string Name { get; set; }
public object Value{
get
{
return GetValue();
}
}
}
class Setting<T> : BaseSetting
{
public Setting(string name, T value, T def) { Name = name; Value = value; DefaultValue = def; }
public new T Value { get; set; }
public T DefaultValue { get; set; }
protected override object GetValue()
{
return Value;
}
}
public class Program
{
public static void Main()
{
// Create iterable list of settings:
List<BaseSetting> Settings = new List<BaseSetting>();
Settings.Add(new Setting<int>("IntSetting", 123, 456));
Settings.Add(new Setting<bool>("BoolSetting", true, false));
Settings.Add(new Setting<double>("FloatSetting", 3.14, 2.718));
// Iterate settings to do something (i.e. save all settings to a file)
foreach(var s in Settings)
{
Console.WriteLine("Name of setting: " s.Name);
Console.WriteLine("Value of setting: " s.Value.ToString()); // ERROR: no member named "Value"
}
}
}
uj5u.com熱心網友回復:
你List
的型別是BaseSetting
. 它不包含這些屬性。
迭代Settings<T>
被提取為BaseSetting
。
要使用Value
etc,您需要轉換s
為適當的型別 - 您需要首先對其進行測驗,這可以通過 來完成is
,但這通常表明解決方案存在缺陷:
if (s is Setting<int>)
//Cast and do stuff with int
因為這不是很有幫助,而且您通常知道如何處理設定 - 它們定義明確 - 設定實作通常只使用字串或明確定義的 JSON 物件。
或者,您可以定義一堆擴展方法,或者基于您的類,object
但在這兩種情況下,您不會獲得更多的收益,而不僅僅是使用string
as Value
,并在需要時進行適當的轉換。
事實上,這也是使用 JSON 反序列化為類時的作業方式 - 但在這種情況下,您必須預先知道您的設定名稱。
uj5u.com熱心網友回復:
因為你的基類沒有 Value 屬性,我們可以嘗試使用abstract
屬性讓子類覆寫它或使用泛型BaseSetting
abstract class BaseSetting
{
public string Name { get; set; }
public abstract object Value { get; set; }
}
class Setting<T> : BaseSetting
{
public Setting(string name, T value, T def) { Name = name; Value = value; DefaultValue = def; }
public override object Value { get; set; }
public T DefaultValue { get; set; }
}
如果您不想使用override
其他方式,我們可以嘗試在建構式中使用new
和設定值base.Value
abstract class BaseSetting
{
public string Name { get; set; }
public object Value { get; set; }
}
class Setting<T> : BaseSetting
{
public Setting(string name, T value, T def) {
Name = name;
base.Value = value;
DefaultValue = def;
}
public new T Value {
get{
return (T)base.Value;
}
set{
base.Value = value;
}
}
public T DefaultValue { get; set; }
}
c# 在線
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/470419.html
上一篇:使用通用鍵索引物件
下一篇:從泛型結構的方法回傳閉包