ADO.NET: SQLConnection
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)]
[global::System.Configuration.DefaultSettingValueAttribute("Data Source=SERVER-SQL\\SQLSERVER_PIK;Initial Catalog=PIK_Rieltor;Integrated Secur" +
"ity=True")]
public string PIK_RieltorConnectionString {
get {
return ((string)(this["PIK_RieltorConnectionString"]));
}
}
public global::System.Data.SqlClient.SqlConnection Connection;
}
}
Но тут есть момент моего непонимания: ведь все эти настройки являются членами класса, посути указатель на объект которого значит где-то должен быть объявлен глобально. Но если посмотреть автоматически сгенерированные участки кода, то можно увидеть, что члены этого класса вызываются не из экземпляра класса, а прямо из него. Но как это? А может Connection лучше хранить не здесь, то где?
Или может я вообще неправильно к этому подхожу?
Вообще сейчас припоминаю две идеи доступа к настройкам SqlConnection. Первый - хранить строку подключения как свойство класса, всегда видимого в главном потоке. Второй - создавать SqlConnection и передавать его как параметр нужным функциям. В моём последнем проекте реализованы обе идеи: главный поток читает настройки и передаёт рабочим потокам строку подключения, а те один раз создают подключение к SQL-серверу и потом просто передают его в свои функции как параметр по ссылке. Кажется, не переврал. Сейчас уточню и скажу, как на самом деле.
Респект. Я предложил то же самое, только долго и непонятно, ну и в терминологии VB.NET. :)
+1, а так же: [COLOR=#0000cc]Пространство имён Rsdn.Framework.Data[/COLOR]
Вообще мне кажется, что это в большой степени заблуждение. Создавать глобальные переменные вообще нехорошая практика, но сделать переменную, видимую глобально, не так уж и сложно, причём способов больше одного. Мы обычно используем передачу объекта (экземпляра класса или его свойства) как параметра по ссылке, можно использовать статические (Shared в VB, static в C#), суть то же самое, отличается в технических деталях. Если речь идёт о параметрах конфигурации, то их можно вообще вынести в XML и читать любым доступным способом в подходящий DataSet, DataTreeView и даже String, короче, так, как лучше всего в данном месте.
...
class TOurClass
{
static SQLConnection Connection;
};
И как я буду создавать Connection не создавая экземпляра класса TOurClass?
А в примере, который написал, ведь Connection необходимо создавать в конструкторе класса TOurClass, а чтобы использовать Connection как глобальную переменную надо вызывать это поле через класс, а не его экземпляр?
Во-первых, потому что переменные должны быть видимыми настолько локально, насколько возможно. Во-вторых, потому что переменную нельзя сделать только для чтения. В третьих, идея глобальных переменных противоречит концепции инкапсуляции. Никто не мешает объявить статическую переменную, и она будет видна глобально, однако при этом, например, обеспечивается такая вещь, как потокобезопасность. В конечном итоге можно просто решить, что такова архитектура, и работать исходя из этого. В самом деле, никого же не смущает, что в Python нет явного объявления переменных?
Это нормально, когда имеется некий совместно используемый ресурс. Яркий пример - как раз SQL-подключение, или имя файла настроек, или сокет, или ещё что угодно. Принцип "Не использовать данные, видимые глобально" не существует. Существует принцип "Не использовать глобальные переменные". Просто статическое поле класса уже не глобальная переменная, хотя и может быть использована таким способом.
Посмотрите в отладчике, это один из лучших способов понять, как это работает. Вот, что говорит Справка: [QUOTE=MSDN]You access a shared element by qualifying it with its class or structure name, not with the variable name of a specific instance of its class or structure. You do not even have to create an instance of a class or structure to access its shared members.[/QUOTE]
2) Поле Connection класса TOurClass нужно сделать public свойством.
2) Поле Connection класса TOurClass нужно сделать public свойством.
Я правильно понимаю:
TOurClass.Connection = Connection;
А при вызове пишу:
Так?
TOurClass.Connection = Connection;
А при вызове пишу:
Так?
Камрад rSolanov! Не сочтите за сноба, но разве не быстрее проверить в редакторе кода? ;)
Код не проверял, но, кажется, верно. Насчёт вызова не уверен, лучше посмотреть в редакторе.
private static SqlConnection connection = null;
public static SqlConnection Connection {
get {
if(connection == null) {
connection = new SqlConnection("ваша строка соединения, можно считать из конфига");
}
return connection;
}
}
}
Скажем так - создавать экземпляр TOurClass не имеет смысла.
...
class TOurClass
{
static SqlConnection Connection;
};
...
TOurClass.Connection = new SqlConnection();
...
Вы также не могли бы пояснить прицип работы: какже если мы не создавая экземпляра объкта в памяти, не создавая адресное пространство в памяти, не получая указатель на созданный объект, через класс вызываем его методы? Хотелось бы понять в этом случае отношения класс-память и вызов метода класса-память
Помните, как учили в советских ВУЗах предметы идеологического направления? Была там знаменитая фраза: "Обращайтесь к первоисточникам:[QUOTE=MSDN]
Shared (Visual Basic)
Specifies that one or more declared programming elements are associated with a class or structure at large, and not with a specific instance of the class or structure.
When to Use Shared
Sharing a member of a class or structure makes it available to every instance, rather than nonshared, where each instance keeps its own copy. This is useful, for example, if the value of a variable applies to the entire application. If you declare that variable to be Shared, then all instances access the same storage location, and if one instance changes the variable's value, all instances access the updated value.
Sharing does not alter the access level of a member. For example, a class member can be shared and private (accessible only from within the class), or nonshared and public.[/QUOTE]Не обращайте внимания на вебедотнет, принцип везде остаётся тот же самый, поскольку на уровне IL различия пропадают. Если жажда исследования одолевает, ILDASM в руки и вперёд - создать класс со статическими переменными и обратиться к ним. Вам наверняка откроется многое, и это полезно для понимания того, что напрямую, впрочем, едва ли удастся использовать. А для решения практических задач достаточно знать, что статическое поле видно отовсюду.;)
Боюсь огорчить, но английский язык в этом деле - lingua franca, и учить его надо любым доступным способом. Точно так же как любой русский дворянин должен был знать французский, хотя, думаю, в принципе прожить мог и без этого. Уж если Дональд Э. Кнут освоил русский в объёме, достаточном для чтения русской математической литературы, то вы, безо всякого сомнения, освоите английский в объёме, достаточном для чтения MSDN без перевода.
Общий смысл таков: в VB.NET атрибут Shared позволяет сделать член класса доступным из любого участка кода и гарантирует потокобезопасность и уникальность её в пределах приложения, а не экземпляра класса, поскольку все экземпляры ссылаются на одну область памяти.
От чтения постов ещё никто, насколько мне известно, святым не стал. ;) О просвещении же говорить несколько наивно, ибо не один раз уже поднималась дискуссия о кризисе этого форума как образовательной сущности. Страждущие же найдут способ понять и английский текст, тем паче, что уже не единожды сказано: английский суть один из пропусков в программирование, полагаю, даже более важный, чем высшая математика.
...
От чтения постов ещё никто, насколько мне известно, святым не стал. ;) О просвещении же говорить несколько наивно, ибо не один раз уже поднималась дискуссия о кризисе этого форума как образовательной сущности. Страждущие же найдут способ понять и английский текст, тем паче, что уже не единожды сказано: английский суть один из пропусков в программирование, полагаю, даже более важный, чем высшая математика.
Готов с Вами согласиться.
Общий смысл таков: в VB.NET атрибут Shared позволяет сделать член класса доступным из любого участка кода и гарантирует потокобезопасность и уникальность её в пределах приложения, а не экземпляра класса, поскольку все экземпляры ссылаются на одну область памяти.
При написании, см. код от тов. hardcase:
Создаётся объект класса SQLConnection c получением на него указателя.
Просто для меня уж очень непривычно видеть обращение к методам через класс, а не через его указатель на экземпляр. Но все же, что при этом с классом ConnectionManager происходит в памяти? Или в памяти отводится адресное пространство только для методов и полей такого класса?
Создаётся объект класса SQLConnection c получением на него указателя.
Просто для меня уж очень непривычно видеть обращение к методам через класс, а не через его указатель на экземпляр. Но все же, что при этом с классом ConnectionManager происходит в памяти? Или в памяти отводится адресное пространство только для методов и полей такого класса?
Полагаю, тут несколько иначе. Создаётся экземпляр такого класса, а указатели возвращаются с одним и тем же значением. Аналог глобальной переменной, но не простой: он обеспечивает потокобезопасность. Как это сделано - вопрос к копателям внутренностей дотнета, я к ним не отношусь. Если вам интересно, попробуйте дебаггер, он показывает нечто похожее на нужную информацию. Опять же, всё это стоит делать только в том случае, если очень хочется разобраться в указателях. Критической необходимости в этом нет - достаточно вдумчиво читать руководящие документы и писать примеры для проверки всего, что не кажется очевидным. С точки зрения практики это более верный путь. В самом деле, что вам до указателей, если в дотнете их в явном виде нет?
Полагаю, тут несколько иначе. Создаётся экземпляр такого класса, а указатели возвращаются с одним и тем же значением.
Да, я так и понял, по приведенному коду от hardcase это очевидно.
В самом деле, что вам до указателей, если в дотнете их в явном виде нет?
Привычка, выработанная годами :-)
Вообще сейчас всё наконец стало совершенно понятно. Спасибо вам всем.