Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > вопрос по статическим членам класса.


Автор: 4ybaka 14.5.2007, 19:22
нужно чтобы до создания экземпляра класса у данного класса был обязательно определен статический член класса.как это реализовать?есть предположение,что както можно это сделать через атрибуты,но дальше предположения мысль не идет...через простую проверку в конструкторе - не катит.

Автор: kobra 14.5.2007, 21:45
для этого есть статические конструкторы.

Автор: 4ybaka 21.5.2007, 18:05
Цитата

для этого есть статические конструкторы.

а если надо инициализировать поле неопределенными параметрами?кот при компиляции не известны...

Автор: Дрон 21.5.2007, 18:33
Цитата(4ybaka @  21.5.2007,  19:05 Найти цитируемый пост)
поле неопределенными параметрами

Совсем-совсем неопределёнными или может всё-таки зависящими, например, от фазы луны? smile

Ты, видимо, не совсем понял, что такое "статический конструктор":
Код
class SomeClass
{
     static SomeClass
     {
           // вот тут мы вычисляем фазу луны и инициализируем всё что нам нужно
     }
}

Автор: 4ybaka 21.5.2007, 19:30
Дрон, 
у нас класс SomeClass вообще не имеет понятия,о том какая строка(например) ему будет передаваться,а значит ничего он расчитать сам не сможет.те нужно просто инициализировать статическую перем класса,но сделать это нужно красиво)

Автор: Дрон 21.5.2007, 20:39
Цитата(4ybaka @  21.5.2007,  20:30 Найти цитируемый пост)
у нас класс SomeClass вообще не имеет понятия,о том какая строка(например) ему будет передаваться,а значит ничего он расчитать сам не сможет

Я чего-то туплю: если класс ничего ни о чём не знает, то чем же тогда инициализировать?

Цитата(4ybaka @  21.5.2007,  20:30 Найти цитируемый пост)
те нужно просто инициализировать статическую перем класса

Э... ну так, а мы о чём?
Я, правда, в первом примере серьёзную опечатку сделал -- скобки метода забыл.

Может вот так будет понятней:
Код
class SomeClass
{
     private static int field1 = 1234; // инициализация константой, известной при компиляции
     private static int field2;

     // статический конструктор
     static SomeClass()
     {
           field2 = 42 * (30 -  GlobalEnvironment.MoonPhase); // инциализация статического поля во время исполнения
     }
}

Статический конструктор вызывается автоматически до создания первого экземпляра класса.

Автор: 4ybaka 21.5.2007, 21:01
так блин,это все и ежу понятно...
Код

class A {
    public static string S;
    public A() { }
}
class B {
    private string str;
    void Fn() {
        //нужно,чтобы уже здесь A.S было равно str
        //но при этом без вызова СПЕЦИАЛЬНО написанного метода или свойства
        //грубо говоря:
        //A.S = str;
        //а A о str НИЧЕГО не знает...или он всетаки телепат;)
        A a = new A(); 
    }
}

надеюсь теперь понятно? smile 


Цитата

Я, правда, в первом примере серьёзную опечатку сделал -- скобки метода забыл.

я бы это не назвал прям такой серьезной опечаткой...;)

Автор: Дрон 21.5.2007, 22:06
4ybaka, хмм... Виноват. Чувствую в эту тему нужен кто-то со свежим взглядом, а то меня сейчас точно заклинит smile

Вообще, мне кажется, что ты усложняешь себе жизнь smile
Можешь словами описать то, что ты хочешь сделать.  Т.е. во-перых, объяснить, почему просто вызов A.S = str; тебя не устраивает?
А во-вторых, зачем вообще такая хитрость нужна? По мне так всё это скорее всего противоречит правилам ООП.

Зачем, например, делать статическую переменную в классе A, если можно str в классе B объявить как public static.
Или зачем вообще ей быть статической, если её инициализация неразрывно связана с созданием объекта.

Как-то всё это странно выглядит. Вроде как, где-то в глубинах сознания, я понимаю, что вся эта конструкция может иметь смысл, но всё же мой опыт говорит мне, что тут что-то не так и можно сделать по-другому smile

Цитата(4ybaka @  21.5.2007,  22:01 Найти цитируемый пост)
я бы это не назвал прям такой серьезной опечаткой...;)

Просто я сначала подумал, что ты вообще про статические конструкторы не знаешь, тогда бы это могло сбить с толку. А так, конечно, ясно про что я хотел сказать smile

Автор: 4ybaka 21.5.2007, 22:22
Цитата

Т.е. во-перых, объяснить, почему просто вызов A.S = str; тебя не устраивает?

это означает,что мы можем в любой момент изменить поле A.S,чего нельзя.даже если поставить защиту на изменение,то это дополнительная переменная(а значит и память),+ сбиваем с толку программиста:"почему этот гребаный метод не работает как надо?!!!!":)

Цитата

Зачем, например, делать статическую переменную в классе A, если можно str в классе B объявить как public static.

эта переменная была приведена для примера.фактически она формируется один раз и удалялется.да и вообще класс А является автономным,поэтому не допускается зависимость от другого класса...

Цитата

Или зачем вообще ей быть статической, если её инициализация неразрывно связана с созданием объекта.

1)назначение статической переменной никак не связано с ее инициализацией.еси есть один Graphics для всего класса,то зачем его делать для каждой переменной?2)ее инициализация должна предшествовать созданию объекта,тк при создании последнего она может потребоваться...

впринципе я начинают понимать,что это не сделать,как я хотел...но если будут предложения,обязательно выслушаю.

Автор: archeg 22.5.2007, 00:35
Передавай в перегружений конструктор строку. Например вот так:
Код

class A {
    public static string S;
    public A() { }
    public A(string str) { A.S = str;} //Перезагружен конструктор. При создании екземпляра необязатнльо указывать строку
}

Автор: Дрон 22.5.2007, 09:00
Попробую ещё раз.

Итак, у нас есть статическая переменная в классе A, которую нужно инициализировать извне, причём инициализировать один единственный раз, ещё до создания первого экземпляра класса. После инициализации, переменную изменять уже нельзя.

Хмм...Статические переменные -- это всё-таки плохо. Например, ты точно уверен, что за всё время выполнения программы тебе не понадобится изменять эту переменную? Мне кажется, это довольно редкий случай.

А так, я бы всё-таки сделал что-то вроде:
Код
private static bool isInitialized;
private static string S;

public static Initialize(string str)
{
    if (!isInitialized)
    {
       S = str;
       isInitialized = true;
    }
    else
    {
        // чтобы не вводить программиста в заблуждение, мы ему сразу скажем, что он опоздал
         throw new InvalidOperationException("Class already initialized.");
    }
}

Автор: ivashkanet 22.5.2007, 09:17
Дрон, ага, так. 

Я так у себя делал:
Сначала инициализируются два класса и сообщают об этом с помощью ContextControlLoaded и WorkControlLoaded. После того как оба загружены создается экземпляр менеджера. Если к нему обращаются до загрузки этих двух частей, то выкидывается исключение.

Код

    Private Shared _pluginManager As PluginManager
    Private Shared _contextControl As NAOMIContextControl
    Private Shared _workControl As NAOMIWorkControl

    Public Shared ReadOnly Property PluginManagerInstance() As PluginManager
        Get
            If _pluginManager Is Nothing Then Throw New InvalidOperationException("Plugin manager has not been initialized yet")
            Return _pluginManager
        End Get
    End Property

    Public Shared Sub ContextControlLoaded(ByVal contextControl As NAOMIContextControl)
        _contextControl = contextControl
        _initializePluginManager()
    End Sub

    Public Shared Sub WorkControlLoaded(ByVal workControl As NAOMIWorkControl)
        _workControl = workControl
        initializePluginManager()
    End Sub

    Private Shared Sub initializePluginManager()
        If _contextControl IsNot Nothing And _workControl IsNot Nothing Then
            _pluginManager = New PluginManager()
        End If
    End Sub

Автор: tol05 22.5.2007, 12:56
Индусы написали бы так smile
Код

class Test
{
  static void Main()
  {
     B b = new B();
     b.Fn();
  }
}

class A
{
  public static string S;

  static A()
  {
     S = B.statStr;
  }
}

class B
{
  public static string statStr = "STAT_STRING";
  public void Fn()
  {
    A a = new A();
  }
}


в момент вызова new A() перед заходом в конструктор экземпляра мы зайдем в статический конструктор. Ну, или когда будем вызывать статический метод класса A.

Автор: 4ybaka 23.5.2007, 16:59
archeg, идея нормальная,но смущает немного то,что придется создавать объект.я конечно понимаю,что на него можно и не обращать внимание,но всеже...


Дрон, я как раз делал именно так,но оказалось,что таких переменных несколько,и меня не порадовала перспектива писать много раз одно и тоже...кстати я уже писал по поводу этого варианта smile 


ivashkanet, а можно по подробней,как это все работает?те просто объяснить принцип действия...например не понятно "Сначала инициализируются два класса",это как?


tol05, ну про индусов я к сожалению промолчал,когда говорил об автономности класса....  smile  

Автор: tol05 23.5.2007, 17:12
Я имел в виду:
- не искать сложного в простом
- про индусов - это моя личная тема smile считай, вторая подпись. Так что к присутствующим она не имеет никакого отношения.

Давай вспомним задачу. Нужно проинициализировать статическую переменную класса, т.е. до создания первого экземпляра класса. Правильно? smile

Как это сделать? Только статическим конструктором. 
Откуда взять данные? Из хранилища, а им может быть что угодно. Кроме, конечно, экземпляра другого класса, т.к. неизвестно, будет ли он вообще создан и когда.
Но в статической переменной хранить - гораздо надежнее. Хоть один класс-хранилище-то будет создан до экземпляра класса А, я надеюсь smile
Ну, раз уж ОН создает A. Так я думал, да и сейчас так же думаю.

А вообще, данные можно хранить где угодно, в БД, в файле, в MemoryStream, разве в этом дело? Разве в этом был вопрос?
Цитата(4ybaka @  14.5.2007,  19:22 Найти цитируемый пост)
нужно чтобы до создания экземпляра класса у данного класса был обязательно определен статический член класса.как это реализовать


Цитата(kobra @  14.5.2007,  21:45 Найти цитируемый пост)
для этого есть статические конструкторы


Вот и все.

Автор: 4ybaka 23.5.2007, 17:33
Цитата

А вообще, данные можно хранить где угодно, в БД, в файле, в MemoryStream, разве в этом дело? Разве в этом был вопрос?

хм...ну вообщем да.надо обмозговать... smile спасибо.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)