Лучший отвечающий
C# где объявить объект для его глобальной видимости?

Вопрос
-
Я понимаю что понятие глобальной переменной в C# нет, но суть в том что при старте программы она загружает настройки в некий объект, далее они повсеместно используются. На данный момент я объявил объект в главной форме, в дочернем окне (SDI интерфейс), AppSettings уже "Не существует в текущем контексте", а передавать повсюду и повсеместно ссылку на объект хранящий переменные как-то излишне.
Могу ли я объявить объект в где-то в program.cs чтоб он был виден везде?
- Перемещено Siddharth Chavan 1 октября 2010 г. 21:36 MSDN Forums Consolidation (От:Visual C#)
24 марта 2010 г. 7:56
Ответы
-
Создавайте экземляр этого класса как статический член любого класса оболочки - поместите этот класс в области видимости всех форм и через статическое свойство спокойно получайте доступ к единственному экземпляру вашего объекта AppSett
public class AppSetWrapper { //хранит настройки private Settings appSettings; //конструктор выполняется один раз при запуске приложения static AppSetWrapper { appSettings = Settings.Create(...); } //Получаем доступ к объекту-свойствам public static Settings AppSettingsInstance { get { return appSettings; } } } где - то public Form1 : Form { public void Method() { MessageBox.Show(AppSetWrapper.AppSettingsInstance) } } public Form2 : Form { public void Method() { MessageBox.Show(AppSetWrapper.AppSettingsInstance) } }
и т.д. Один экземпляр объекта-свойств на все формы во всем приложении, что собственно в начале и было написано.- Помечено в качестве ответа PhantomSL 24 марта 2010 г. 16:45
24 марта 2010 г. 9:07 -
Ну в форму его не надо помещать, зачем - это же глобальные настройки для всего приложения. В принципе его не надо вобще делать вложенным класом, поместите его в то же пространство имен, где ваш класс Program объявлен, хотя бы вот так:
namespace WindowsFormsApplication2 { static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } public class AppSetWrapper { //хранит настройки private Settings appSettings; //конструктор выполняется один раз при запуске приложения static AppSetWrapper { appSettings = Settings.Create(...); } //Получаем доступ к объекту-свойствам public static Settings AppSettingsInstance { get { return appSettings; } } } }
Ну это все дело удобства, а теоретически его куда угодно можно поместить. В частности VS добавляет автоматически пространство имен Properties с кдассом глобальных настроек Settings - его и туда можно поместить.24 марта 2010 г. 12:56
Все ответы
-
Вот пример
public class MySettinfg { private MySettinfg() { } public string MySetting1 { get { return "setting1"; } } public string MySetting2 { get { return "setting2"; } } private static MySettinfg instance; static MySettinfg() { instance = new MySettinfg(); } public static MySettinfg Setting { get { return instance; } } }
24 марта 2010 г. 8:11 -
Видимо я или не понял сути или не верно задал вопрос, так что вношу дополнения:
1. Я не нашел более менее вразумительно способа для сохранения настроек в .Net Compact в итоге был написан такой класс:
[Serializable] [XmlRootAttribute("Settings", Namespace = "", IsNullable = true)] public class Settings { private string FileName; private XmlWriterSettings xws; private Settings() { } //Обязательное условие для сериализации и значения по умолчанию public static Settings Create(string SettFileName) { //Создаем новый экземпляр Settings Res = new Settings(); if (File.Exists(SettFileName)) //Если файл существует, то загружаем { XmlSerializer serializer = new XmlSerializer(Res.GetType()); using (Stream SerStream = new FileStream(SettFileName, FileMode.Open)) { Res = (Settings)serializer.Deserialize(SerStream); } //SerStream.Close(); } Res.FileName = SettFileName; //Так как обнуляется в процессе сериализации //Сохранение в нужной мне кодировке Res.xws = new XmlWriterSettings(); Res.xws.Encoding = Encoding.GetEncoding(1251); Res.xws.Indent = true; return Res; } //Сохранение настроек в файл public void Save() { //Подключаем к потоку вывода using (Stream SerStream = new FileStream(FileName, FileMode.Create, FileAccess.Write, FileShare.None)) { XmlWriter xw = XmlWriter.Create(SerStream, xws); XmlSerializer serializer = new XmlSerializer(this.GetType()); serializer.Serialize(xw, this); xw.Close(); } //SerStream.Close(); } //Собственно сами сохраняемые переменные //Со значениями по умолчанию public string IP = "196.68.8.51";//"192.168.1.1"; public int Port = 9002; }
И он задействуется: в главной форме://Объявление в классе формы Settings AppSett; //Считываем настройки в Load AppSett = Settings.Create(MainPath + "AppSett.txt"); //Сохраняем в Close AppSett.Save();
Так что .Net Compact и условия XML сериализации несколько сдерживают применение статических классов и т.д. Вот я и спрашивал ГДЕ именно объявить Settings Appset чтоб видеть в дочерних формах?24 марта 2010 г. 8:41 -
Вам необходимо создать public класс-сингльтон, в который при старте нужно записывать данные и потом использовать где-либо в приложении.
Как создать класс-сингльтон, описано здесь: http://www.yoda.arachsys.com/csharp/singleton.html
24 марта 2010 г. 9:03 -
Создавайте экземляр этого класса как статический член любого класса оболочки - поместите этот класс в области видимости всех форм и через статическое свойство спокойно получайте доступ к единственному экземпляру вашего объекта AppSett
public class AppSetWrapper { //хранит настройки private Settings appSettings; //конструктор выполняется один раз при запуске приложения static AppSetWrapper { appSettings = Settings.Create(...); } //Получаем доступ к объекту-свойствам public static Settings AppSettingsInstance { get { return appSettings; } } } где - то public Form1 : Form { public void Method() { MessageBox.Show(AppSetWrapper.AppSettingsInstance) } } public Form2 : Form { public void Method() { MessageBox.Show(AppSetWrapper.AppSettingsInstance) } }
и т.д. Один экземпляр объекта-свойств на все формы во всем приложении, что собственно в начале и было написано.- Помечено в качестве ответа PhantomSL 24 марта 2010 г. 16:45
24 марта 2010 г. 9:07 -
Вам необходимо создать public класс-сингльтон, в который при старте нужно записывать данные и потом использовать где-либо в приложении.
Как создать класс-сингльтон, описано здесь: http://www.yoda.arachsys.com/csharp/singleton.html
Посмотрите выше и убедитесь, что у меня и есть непотокобезопасный синглтон.24 марта 2010 г. 9:09 -
Такой вариант
public static class MySettings { public static Dictionary<string, object> Setings { get; set; } static MySettings() { Setings = new Dictionary<string, object>(); Setings.Add("something", "something to put"); } }
[Test] public void GetSomethigWhatAdedWhenAplicationStart() { Assert.AreEqual("something to put", (string)MySettings.Setings["something"]); } [Test] public void AddSettingsProgrammatically() { Object objectToPut = new object(); MySettings.Setings.Add("myObj", objectToPut); Assert.AreSame(objectToPut, MySettings.Setings["myObj"]); }
24 марта 2010 г. 9:48 -
>> Посмотрите выше и убедитесь, что у меня и есть непотокобезопасный синглтон.
Убедился. Но, думаю, нужно было описать, почему именно такой код нужно использовать.
24 марта 2010 г. 10:01 -
>> Посмотрите выше и убедитесь, что у меня и есть непотокобезопасный синглтон.
Убедился. Но, думаю, нужно было описать, почему именно такой код нужно использовать.
Да.. в любом случае ответ получен.24 марта 2010 г. 10:08 -
"Создавайте экземляр этого класса как статический член любого класса оболочки - поместите этот класс в области видимости всех форм и через статическое свойство спокойно получайте доступ к единственному экземпляру вашего объекта AppSett"
Я новичек в C# и меня более всего интересует "поместите этот класс в области видимости всех форм"
1.
private Settings appSettings
Может быть полем "static class Program" или "public partial class fmMainForm : Form" если нет, то созданный только для отражения "public class AppSetWrapper" где должен объявляться в файле "program.cs" или в файле содержащем класс формы?
24 марта 2010 г. 11:55 -
Ну в форму его не надо помещать, зачем - это же глобальные настройки для всего приложения. В принципе его не надо вобще делать вложенным класом, поместите его в то же пространство имен, где ваш класс Program объявлен, хотя бы вот так:
namespace WindowsFormsApplication2 { static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } public class AppSetWrapper { //хранит настройки private Settings appSettings; //конструктор выполняется один раз при запуске приложения static AppSetWrapper { appSettings = Settings.Create(...); } //Получаем доступ к объекту-свойствам public static Settings AppSettingsInstance { get { return appSettings; } } } }
Ну это все дело удобства, а теоретически его куда угодно можно поместить. В частности VS добавляет автоматически пространство имен Properties с кдассом глобальных настроек Settings - его и туда можно поместить.24 марта 2010 г. 12:56 -
А разве статическому конструктору или свойству можно оперировать с не статическими данными коими является appSettings?
У меня VS ругается на "Для нестатического поля, метода или свойства "DelSmart.AppSetWrapper.appSettings" требуется ссылка на объект"
24 марта 2010 г. 14:07 -
Судя по всему
private Settings appSettings тоже надо static
24 марта 2010 г. 16:26 -
Судя по всему
private Settings appSettings тоже надо static
Ага, я просто так набивал - не компилил, поэтому прошла ошибка.
24 марта 2010 г. 21:16