Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么';在C#中,处理不同数据类型的值的公认方法是什么?_C# - Fatal编程技术网

什么';在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:因为这是正确的解决方案,所以不清楚如何继承