什么';在C#中,处理不同数据类型的值的公认方法是什么?
我基本上是在读一个配置文件什么';在C#中,处理不同数据类型的值的公认方法是什么?,c#,C#,我基本上是在读一个配置文件 [部分] 键=值 其中,值可以是字符串、整数、双精度或布尔值 在这种环境下工作时,我有一个类看起来像这样 public class Setting { public string Section {get; set;} public string Key {get; set;} public <string, int, double, or bool> Value {get; set;} public Setting(st
[部分]
键=值
其中,值可以是字符串、整数、双精度或布尔值
在这种环境下工作时,我有一个类看起来像这样
public class Setting
{
public string Section {get; set;}
public string Key {get; set;}
public <string, int, double, or bool> Value {get; set;}
public Setting(string section, string key, <string, int, double, or bool> value)
{
Section = section;
Key = key;
Value = value;
}
public void Write()
{
//if Value is an int, call third-party code to write an integer to the config file.
//if Value is a string, call third-party code to write a string to the config file.
//...
}
}
public class Setting<T>
{
public string Section { get; set; }
public string Key { get; set; }
public T Value { get; set; }
public Setting(string section, string key, T value)
{
Section = section;
Key = key;
Value = value;
}
public void Write()
{
switch (Type.GetTypeCode(typeof(T)))
{
case TypeCode.Int32:
//Call third-party code to write an integer
break;
case TypeCode.String:
//Call third-party code to write a string
break;
default:
break;
}
}
}
但是我只能在列表中存储一种类型的设置
System.Collections.Generic.List<Setting<string>> settings = new List<Setting<string>>();
但这似乎有很多重复的代码,因此将来进行更改可能很容易出错
更新:
另一个选项是将Value
设置为动态类型
public class DynamicSetting
{
public string Section { get; set; }
public string Key { get; set; }
public dynamic Value { get; set; }
public DynamicSetting(string section, string key, dynamic value)
{
Section = section;
Key = key;
Value = value;
}
public void Write()
{
switch (Type.GetTypeCode(Value.GetType()))
{
case TypeCode.Int32:
//Call third-party code to write an integer
break;
case TypeCode.String:
//Call third-party code to write a string
break;
default:
break;
}
}
}
然后我可以创建一组DynamicSetting对象,并将它们存储在我想要的集合中
DynamicSetting IntSetting = new DynamicSetting("Section", "Key", 1);
DynamicSetting StringSetting = new DynamicSetting("Section", "Key", "1");
DynamicSetting DoubleSetting = new DynamicSetting("Section", "Key", 1.0);
System.Collections.Generic.List<DynamicSetting> settings = new List<DynamicSetting>();
settings.Add(IntSetting);
settings.Add(StringSetting);
settings.Add(DoubleSetting);
foreach(DynamicSetting setting in settings)
{
setting.Write();
}
它会像动态的一样工作
ObjectSetting IntSetting = new ObjectSetting("Section", "Key", 1);
ObjectSetting StringSetting = new ObjectSetting("Section", "Key", "1");
ObjectSetting DoubleSetting = new ObjectSetting("Section", "Key", 1.0);
System.Collections.Generic.List<ObjectSetting> settings = new List<ObjectSetting>();
settings.Add(IntSetting);
settings.Add(StringSetting);
settings.Add(DoubleSetting);
foreach(ObjectSetting setting in settings)
{
setting.Write();
}
ObjectSetting IntSetting=新的ObjectSetting(“节”、“键”,1);
ObjectSetting StringSetting=新的ObjectSetting(“节”、“键”、“1”);
ObjectSetting DoubleSetting=新的ObjectSetting(“节”、“键”,1.0);
System.Collections.Generic.List设置=新建列表();
设置。添加(IntSetting);
设置。添加(字符串设置);
设置。添加(双重设置);
foreach(设置中的对象设置)
{
set.Write();
}
最简单的方法是在构造函数和setter中接受值作为对象,这两种方法都会根据有效类型列表验证类型。在Write方法中使用开关来确定要调用的第三方代码。您可以将所有设置存储在一个集合中。或者,您可以为构造函数和SetValue方法编写重载。这需要更多的代码,但会提供设计时类型检查。最简单的方法是在构造函数和setter中接受值作为对象,这两种方法都会根据有效类型列表验证类型。在Write方法中使用开关来确定要调用的第三方代码。您可以将所有设置存储在一个集合中。或者,您可以为构造函数和SetValue方法编写重载。这是更多的代码,但将提供设计时类型检查。ISettingValue示例:
public interface ISettingValue
{
void Write();
}
public class StringSetting : ISettingValue
{
readonly string _data;
public StringSetting(string data) => _data = data;
public void Write()
{
//Call third-party code to write the string (value of _data).
}
}
public class IntSetting : ISettingValue
{
readonly int _data;
public IntSetting(int data) => _data = data;
public void Write()
{
//Call third-party code to write the integer (value of _data).
}
}
public class Setting
{
public string Section { get; set; }
public string Key { get; set; }
public ISettingValue Value { get; set; }
public Setting(string section, string key, ISettingValue value)
{
Section = section;
Key = key;
Value = value;
}
public void Write()
{
Value.Write();
}
}
ISettingValue的示例:
public interface ISettingValue
{
void Write();
}
public class StringSetting : ISettingValue
{
readonly string _data;
public StringSetting(string data) => _data = data;
public void Write()
{
//Call third-party code to write the string (value of _data).
}
}
public class IntSetting : ISettingValue
{
readonly int _data;
public IntSetting(int data) => _data = data;
public void Write()
{
//Call third-party code to write the integer (value of _data).
}
}
public class Setting
{
public string Section { get; set; }
public string Key { get; set; }
public ISettingValue Value { get; set; }
public Setting(string section, string key, ISettingValue value)
{
Section = section;
Key = key;
Value = value;
}
public void Write()
{
Value.Write();
}
}
也许是那样的
public abstract class Setting {
public abstract Type keyType { get; }
public string Key { get; protected set; }
public object value { get; protected set; }
protected abstract Action writer { get; }
public void Write() => writer();
}
public class Setting<T> : Setting {
public override Type keyType => typeof(T);
protected override Action writer => () => typeWriter(Value);
public string Section { get; set; }
public T Value {get; set;}
private Action<T> typeWriter { get; }
public Setting(string section, string key, T value, Action<T> writer) {
Section = section;
Key = key;
this.value = Value = value;
typeWriter = writer;
}
}
public class Usage {
private List<Setting> settings = new List<Setting>() {
new Setting<double>("", "x", 10, n => Debug.WriteLine(n % 4)),
new Setting<string>("", "y", "abc", s => Debug.WriteLine(s.ToUpper())),
new Setting<bool>("", "z", true, b => Debug.Write(!b)),
};
public Usage() {
foreach (var s in settings) {
Debug.Write($"{s.keyType.Name} {s.Key} =");
s.Write();
}
}
}
公共抽象类设置{
公共抽象类型keyType{get;}
公共字符串密钥{get;protected set;}
公共对象值{get;protected set;}
受保护的抽象操作编写器{get;}
public void Write()=>writer();
}
公共类设置:设置{
公共覆盖类型keyType=>typeof(T);
受保护的覆盖操作写入程序=>()=>打字机(值);
公共字符串部分{get;set;}
公共T值{get;set;}
私人操作打字机{get;}
公共设置(字符串部分、字符串键、T值、动作编写器){
截面=截面;
钥匙=钥匙;
这个。值=值=值;
打字机=打字机;
}
}
公共类用法{
私有列表设置=新列表(){
新设置(“,”x“,10,n=>Debug.WriteLine(n%4)),
新设置(“,“y”,“abc”,s=>Debug.WriteLine(s.ToUpper()),
新设置(“,”z“,true,b=>Debug.Write(!b)),
};
公共用途(){
foreach(设置中的变量s){
Debug.Write($“{s.keyType.Name}{s.Key}=”);
s、 Write();
}
}
}
也许是这样的
public abstract class Setting {
public abstract Type keyType { get; }
public string Key { get; protected set; }
public object value { get; protected set; }
protected abstract Action writer { get; }
public void Write() => writer();
}
public class Setting<T> : Setting {
public override Type keyType => typeof(T);
protected override Action writer => () => typeWriter(Value);
public string Section { get; set; }
public T Value {get; set;}
private Action<T> typeWriter { get; }
public Setting(string section, string key, T value, Action<T> writer) {
Section = section;
Key = key;
this.value = Value = value;
typeWriter = writer;
}
}
public class Usage {
private List<Setting> settings = new List<Setting>() {
new Setting<double>("", "x", 10, n => Debug.WriteLine(n % 4)),
new Setting<string>("", "y", "abc", s => Debug.WriteLine(s.ToUpper())),
new Setting<bool>("", "z", true, b => Debug.Write(!b)),
};
public Usage() {
foreach (var s in settings) {
Debug.Write($"{s.keyType.Name} {s.Key} =");
s.Write();
}
}
}
公共抽象类设置{
公共抽象类型keyType{get;}
公共字符串密钥{get;protected set;}
公共对象值{get;protected set;}
受保护的抽象操作编写器{get;}
public void Write()=>writer();
}
公共类设置:设置{
公共覆盖类型keyType=>typeof(T);
受保护的覆盖操作写入程序=>()=>打字机(值);
公共字符串部分{get;set;}
公共T值{get;set;}
私人操作打字机{get;}
公共设置(字符串部分、字符串键、T值、动作编写器){
截面=截面;
钥匙=钥匙;
这个。值=值=值;
打字机=打字机;
}
}
公共类用法{
私有列表设置=新列表(){
新设置(“,”x“,10,n=>Debug.WriteLine(n%4)),
新设置(“,“y”,“abc”,s=>Debug.WriteLine(s.ToUpper()),
新设置(“,”z“,true,b=>Debug.Write(!b)),
};
公共用途(){
foreach(设置中的变量s){
Debug.Write($“{s.keyType.Name}{s.Key}=”);
s、 Write();
}
}
}
这要看情况而定。有时我使用对象
类型。。。有时是泛型T
类型。它是一个字符串。是否可以转换取决于考虑添加EnUM类型。不要使用INI文件。该文件包含字符串。如何处理该字符串取决于您的代码。如果您已经知道每个部分包含的内容,那么可以为每个部分创建不同的类,并为每个设置创建特定的类型属性。如果你不知道它包含什么,字符串是唯一的选项,这取决于“int-stuff”和“string-stuff”是什么。它可以作为对象
或泛型类型完成吗?如果不是,继承是一种选择。@Tester101:因为这是正确的解决方案,所以我不清楚您为什么要避免它。你为什么要回避正确的解决方案?这要看情况而定。有时我使用对象
类型。。。有时是泛型T
类型。它是一个字符串。是否可以转换取决于考虑添加EnUM类型。不要使用INI文件。该文件包含字符串。如何处理该字符串取决于您的代码。如果您已经知道每个部分包含的内容,那么可以为每个部分创建不同的类,并为每个设置创建特定的类型属性。如果你不知道它包含什么,字符串是唯一的选项,这取决于“int-stuff”和“string-stuff”是什么。它可以作为对象
或泛型类型完成吗?如果不是,继承是一个选项。@Tester101:因为这是正确的解决方案,所以不清楚如何继承