Здравствуйте, ghostrider, Вы писали:
AVK>>Ты забыл сказать чего ты собственно хочешь добиться и зачем. G>наличия строковых констант на которые я мог бы в любой момент ссылаться в своем коде (из другой сборки)
Ссылайся наздоровье на обычные константы? Что мешает?
G>>>II)и аналогичный вопрос с атрибутами. если у меня в сборке определен атрибут, то его конструктор вызовется только в случае вызова кем-то Assembly.GetCustomAttributes. AVK>>А как тебе хочется? G>хочется всего и побольше и чтобы ничего за это не было G>на самом деле, я рассчитывал, что конструктор выполниться при загрузке сборки.
При загрузке сборки не выполняется никакого кода. Это следует запомнить.
G>я хотел сделать атрибут с "побочным эффектом" (например создать экземпляр класса определенного типа),
Это кривой дизайн. Старайся подобного избегать.
G> но если действие этого эффекта всеравно нужно вызывать явно, то тогда просто уж лучше в своей сборке сделать какой-нить Init() с нужными параметрами
Это тоже криво. Лучше если нужная тебе инициализация будет происходить при первом обращении к твоему классу.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, ghostrider, Вы писали:
AVK>>>Ты забыл сказать чего ты собственно хочешь добиться и зачем. G>>наличия строковых констант на которые я мог бы в любой момент ссылаться в своем коде (из другой сборки)
AVK>Ссылайся наздоровье на обычные константы? Что мешает?
Имхо, перед тем как такое советовать, следует посмотреть, что компилятор сделает с обращением к такой константе.
Вот пример:
1-ая сборка:
namespace Test1
{
public class ClassA
{
public const string CONST = "Const 2";
}
}
2-ая сборка:
using System;
namespace Test2
{
public class ClassB
{
public static void Main()
{
Console.WriteLine(Test1.ClassA.CONST);
}
}
}
IL метода Main из второй сборки:
.method public hidebysig static void Main() cil managed
{
.entrypoint// Code size 11 (0xb).maxstack 1
IL_0000: ldstr"Const 2"
IL_0005: call void [mscorlib]System.Console::WriteLine(string)
IL_000a: ret
} // end of method ClassB::Main
Как видишь, в IL-е никакого обращения к статической переменной нет. Вместо этого компилятор подставил строковый литерал. Поэтому, если ты измнишь в первой сборке определение CONST, и пересоберешь ее, не пересобирая сборку 2, то ничего хорошего после этого не будет (во второй сборке останется прежднее значение CONST).
Re: какого цвета роза, когда на нее никто не смотрит?
class Tags
{
public static const String tag1 = "tag1";
public static const String tag2 = "tag2";
// Ессно, так нельзя, надо или (1)public const String tag1 = "tag1";
public const String tag2 = "tag2";
// или (2)public static String tag1 = "tag1";
public static String tag2 = "tag2";
}
тут и начинается интересное:
если писать (1), то до первого вызова какого-нибудь метода у Tags константы неинициализорованны
если (2), то константы получаются неконстантными, что не есть идеологически правильно
конструктор типа вопроса не решает, т.к. вызывается в том же случае, что и (1)
можно, конечно, забить и написать static, но может можно сделать это и как-то правильно.
II)и аналогичный вопрос с атрибутами. если у меня в сборке определен атрибут, то его конструктор вызовется только в случае вызова кем-то Assembly.GetCustomAttributes.
Re: какого цвета роза, когда на нее никто не смотрит?
Здравствуйте, ghostrider, Вы писали:
G>если писать (1), то до первого вызова какого-нибудь метода у Tags константы неинициализорованны G>если (2), то константы получаются неконстантными, что не есть идеологически правильно G>конструктор типа вопроса не решает, т.к. вызывается в том же случае, что и (1)
Ты забыл сказать чего ты собственно хочешь добиться и зачем.
G>II)и аналогичный вопрос с атрибутами. если у меня в сборке определен атрибут, то его конструктор вызовется только в случае вызова кем-то Assembly.GetCustomAttributes.
G>>если писать (1), то до первого вызова какого-нибудь метода у Tags константы неинициализорованны G>>если (2), то константы получаются неконстантными, что не есть идеологически правильно G>>конструктор типа вопроса не решает, т.к. вызывается в том же случае, что и (1)
AVK>Ты забыл сказать чего ты собственно хочешь добиться и зачем.
наличия строковых констант на которые я мог бы в любой момент ссылаться в своем коде (из другой сборки)
G>>II)и аналогичный вопрос с атрибутами. если у меня в сборке определен атрибут, то его конструктор вызовется только в случае вызова кем-то Assembly.GetCustomAttributes.
AVK>А как тебе хочется?
хочется всего и побольше и чтобы ничего за это не было
на самом деле, я рассчитывал, что конструктор выполниться при загрузке сборки. я хотел сделать атрибут с "побочным эффектом" (например создать экземпляр класса определенного типа), но если действие этого эффекта всеравно нужно вызывать явно, то тогда просто уж лучше в своей сборке сделать какой-нить Init() с нужными параметрами
Re: какого цвета роза, когда на нее никто не смотрит?
Здравствуйте, ghostrider, Вы писали:
G>тут и начинается интересное: G>если писать (1), то до первого вызова какого-нибудь метода у Tags константы неинициализорованны
Неверно, константы в c# всегда статические и инициализируются вместе с типом (но вообще-то, момент их инициализации важен только при иследовании рефакторигом).
Re[5]: какого цвета роза, когда на нее никто не смотрит?
Здравствуйте, Lloyd, Вы писали: L>Имхо, перед тем как такое советовать, следует посмотреть, что компилятор сделает с обращением к такой константе.
L>Как видишь, в IL-е никакого обращения к статической переменной нет. Вместо этого компилятор подставил строковый литерал. Поэтому, если ты измнишь в первой сборке определение CONST, и пересоберешь ее, не пересобирая сборку 2, то ничего хорошего после этого не будет (во второй сборке останется прежднее значение CONST).
собственно я уже хотел остановиться на варианте со static readonly, но заглянул в il-код который у меня получился с const и вот что я там нашел:
сборка 1 (c#)
public class Tags
{
public const String PAGES = "Pages";
public const String PARENT = "Parent";
public const String KIDS = "Kids";
public const String COUNT = "Count";
public const String TYPE = "Type";
public const String PAGE = "Page";
public const String MEDIABOX = "MediaBox";
public const String CONTENTS = "Contents";
};
Здравствуйте, Lloyd, Вы писали:
L>Как видишь, в IL-е никакого обращения к статической переменной нет. Вместо этого компилятор подставил строковый литерал.
Правильно. На то константа и нужна. Если хочешь иметь константные значения, зависящие от сборки то используй перечисление или read only свойство
L> Поэтому, если ты измнишь в первой сборке определение CONST, и пересоберешь ее, не пересобирая сборку 2, то ничего хорошего после этого не будет (во второй сборке останется прежднее значение CONST).
Не надо просто использовать константы для того для чего они не предназначены. Я же ведь не зря тебя спросил — чего ты хочешь.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Lloyd, Вы писали:
L>>Как видишь, в IL-е никакого обращения к статической переменной нет. Вместо этого компилятор подставил строковый литерал.
AVK>Правильно. На то константа и нужна. Если хочешь иметь константные значения, зависящие от сборки то используй перечисление или read only свойство
Пожалуй, перечисление тоже не корректно использовать. С ним та же проблема, что и с константами. Если не будет использоваться объект этого перечисления (а ты именно так и предлагаешь с ним работать), то при компиляции будет происходить таже банальная замена, что и в случае с константами. То есть опять же будет соблюдена независимость от внешней сборки.
Re[3]: какого цвета роза, когда на нее никто не смотрит?
Здравствуйте, ghostrider, Вы писали:
AVK>>А как тебе хочется? G>хочется всего и побольше и чтобы ничего за это не было G>на самом деле, я рассчитывал, что конструктор выполниться при загрузке сборки. я хотел сделать атрибут с "побочным эффектом" (например создать экземпляр класса определенного типа), но если действие этого эффекта всеравно нужно вызывать явно, то тогда просто уж лучше в своей сборке сделать какой-нить Init() с нужными параметрами
"что-бы конструктор выполнился при загрузке сборки" — это в корне порочное решение. Попытка реализовать подобное привела-бы к куче побочных эффектов. например у нас нет прав на выполнение кода в этой сборке — что должно произойти в случае ее загрузки? тоже самое и с классом.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[6]: какого цвета роза, когда на нее никто не смотрит?
TK>"что-бы конструктор выполнился при загрузке сборки" — это в корне порочное решение. Попытка реализовать подобное привела-бы к куче побочных эффектов. например у нас нет прав на выполнение кода в этой сборке — что должно произойти в случае ее загрузки? тоже самое и с классом.
я не вижу недостатков по сравнению с исполнением в случае вызова GetCustomAttributes() — те же самые неоднозначности + неодназначность насчет того будет ли вызван конструктор вообще или нет
... << RSDN@Home 1.0 beta 6a >>
Re[5]: какого цвета роза, когда на нее никто не смотрит?
Здравствуйте, Lloyd, Вы писали: L>IL метода Main из второй сборки:
L> L>
L>.method public hidebysig static void Main() cil managed
L>{
L> .entrypoint
L> // Code size 11 (0xb)
L> .maxstack 1
L> IL_0000: ldstr"Const 2"
L> IL_0005: call void [mscorlib]System.Console::WriteLine(string)
L> IL_000a: ret
L>} // end of method ClassB::Main
L>
L>Как видишь, в IL-е никакого обращения к статической переменной нет. Вместо этого компилятор подставил строковый литерал. Поэтому, если ты измнишь в первой сборке определение CONST, и пересоберешь ее, не пересобирая сборку 2, то ничего хорошего после этого не будет (во второй сборке останется прежднее значение CONST).
Дядюшка Джефф в "Программировании на платформе .Net" так и написал в Главе 8
"Константы и поля".
И там же цитирую:
— "Нельзя применять константы, если модуль должен задействовать значение, определенное
в другом модуле, во время выполнения. В этом случае вместо констант следует использовать неизменяемые поля."