我正在尝试创建一个包含两个(或更多)离散设置集的程序,这两个设置都符合相同的界面。特别是我想使用设计器生成的设置执行以下操作:
IMySettings settings = Properties.A;
Console.WriteLine(settings.Greeting);
settings = Properties.B;
Console.WriteLine(settings.Greeting);
这对于Go的接口来说是微不足道的,因为可以分配提供方法的任何类(?),但是如何使用其严格的接口实现规则在C#中实现它?
注意:C#/。NET 2.0
答案 0 :(得分:2)
VS中生成的Properties.Settings类不允许您这样做。考虑定义一个简单的DTO类并使用XmlAttribute对其进行标记,以便您可以轻松地对其进行反序列化。
答案 1 :(得分:1)
您也可以在C#中使用接口。
但是,如果您仍想使用设计器生成的设置,则必须编写外观类。
答案 2 :(得分:1)
我不确定你问的是如何在C#中实现接口。
如果是,只需制作类似:
Public Interface IMySettings {
Public string Greeting {get;set;}
}
然后让您的“A”和“B”实现此界面并返回您想要的问候语。因此,您的Properties类将实现IMySettings而不是直接类:
Public class Properties {
public IMySettings A {get;set;}
public IMySettings B {get;set;}
}
因此,代码不是使用“MySettings”,而是代码如下:
IMySettings settings = Properties.A;
答案 3 :(得分:1)
我不确定你是否可以通过设计师生成的设置做到这一点,但我不经常使用它们所以我可能错了。但是,您可以采用另一种方法:创建自己的ConfigurationSection。
以下是一个例子:
public class MyProperties : ConfigurationSection {
[ConfigurationProperty("A")]
public MySettings A
{
get { return (MySettings )this["A"]; }
set { this["A"] = value; }
}
[ConfigurationProperty("B")]
public MySettings B
{
get { return (MySettings )this["B"]; }
set { this["B"] = value; }
}
}
public class MySettings : ConfigurationElement {
[ConfigurationProperty("greeting")]
public string Greeting
{
get { return (string )this["greeting"]; }
set { this["greeting"] = value; }
}
}
然后你的app.config / web.config需要以下内容:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="mySettings" type="Namespace.MyProperties, Assembly"/>
</configSections>
<mySettings>
<A greeting="Hello from A!" />
<B greeting="Hello from B" />
</mySettings>
</configuration>
可能存在错别字,但整体想法是存在的。希望有所帮助。
答案 4 :(得分:0)
您可以使用自定义代码生成器将您的界面插入生成的代码中(使用此处的方法:http://brannockdevice.blogspot.co.uk/2006_01_22_archive.html)。它非常简单和非常整洁,但问题是,如果您在团队中工作,那么他们都需要更新他们的注册表来构建解决方案。
另一个选项,也许是对原始问题最接近的答案,是创建一个通用属性类,然后填充,可能通过显式转换 -
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
namespace ConsoleApplication6
{
// use this class if you plan to add lots more settings files in future (low maintenance)
class GenericProps1
{
public string TestString { get; private set; }
// single cast for all settings files
public static explicit operator GenericProps1(ApplicationSettingsBase props)
{
return new GenericProps1() { TestString = props.Properties["TestString"].DefaultValue.ToString() };
}
}
// use this class if you do NOT plan to add lots more settings files in future (nicer code)
class GenericProps2
{
public string TestString { get; private set; }
// cast needed for settings1 file
public static explicit operator GenericProps2(Properties.Settings1 props)
{
return new GenericProps2() { TestString = props.TestString };
}
// cast needed for settings 2 file
public static explicit operator GenericProps2(Properties.Settings2 props)
{
return new GenericProps2() { TestString = props.TestString };
}
// cast for settings 3,4,5 files go here...
}
class Program
{
// usage
static void Main(string[] args)
{
GenericProps1 gProps1_1 = (GenericProps1)Properties.Settings1.Default;
GenericProps1 gProps1_2 = (GenericProps1)Properties.Settings2.Default;
//or
GenericProps2 gProps2_1 = (GenericProps2)Properties.Settings1.Default;
GenericProps2 gProps2_2 = (GenericProps2)Properties.Settings2.Default;
}
}
}