Programing

정적 생성자의 사용은 무엇입니까?

lottogame 2020. 3. 22. 10:37
반응형

정적 생성자의 사용은 무엇입니까?


정적 생성자의 사용법을 알려주십시오. 정적 생성자를 생성하는 이유와시기는 무엇이며 오버로드 할 수 있습니까?


아니오 당신은 그것을 오버로드 할 수 없습니다; 정적 생성자는 유형 (또는 다른 유형별 작업)과 관련된 정적 필드를 초기화하는 데 유용합니다. 특히 필요한 구성 데이터를 읽기 전용 필드 등으로 읽는 데 유용합니다.

처음 필요할 때 런타임에 자동으로 실행됩니다 (정확한 규칙이 복잡하고 ( "beforefieldinit"참조) CLR2와 CLR4간에 미묘하게 변경됩니다). 리플렉션을 남용하지 않는 한 두 스레드가 동시에 도착하더라도 최대 한 번만 실행 됩니다 .


에서 정적 생성자 (C #을 가이드 프로그래밍) :

정적 생성자는 정적 데이터를 초기화하거나 한 번만 수행해야하는 특정 작업을 수행하는 데 사용됩니다. 첫 번째 인스턴스가 작성되거나 정적 멤버가 참조되기 전에 자동으로 호출됩니다.

정적 생성자는 다음과 같은 속성을 갖습니다.

  • 정적 생성자는 액세스 수정자를 사용하지 않거나 매개 변수를 갖지 않습니다.

  • 첫 번째 인스턴스를 만들거나 정적 멤버를 참조하기 전에 클래스를 초기화하기 위해 정적 생성자가 자동으로 호출됩니다.

  • 정적 생성자는 직접 호출 할 수 없습니다.

  • 정적 생성자가 프로그램에서 실행될 때 사용자는 제어 할 수 없습니다.

  • 정적 생성자의 일반적인 사용은 클래스가 로그 파일을 사용하고 생성자가이 파일에 항목을 쓰는 데 사용되는 경우입니다.

  • 정적 생성자는 생성자가 LoadLibrary메서드를 호출 할 수있는 경우 관리되지 않는 코드에 대한 래퍼 클래스를 만들 때도 유용합니다 .


정적 생성자는 초기화 순서가 중요하도록 서로 의존하는 정적 필드가있는 경우에도 매우 유용합니다. 필드 순서를 변경하는 포맷터 / 뷰티 파이어를 통해 코드를 실행하면 예상치 못한 null 값이 표시 될 수 있습니다.

예 :이 클래스가 있다고 가정 해 봅시다.

class ScopeMonitor
{
    static string urlFragment = "foo/bar";
    static string firstPart= "http://www.example.com/";
    static string fullUrl= firstPart + urlFragment;
}

에 액세스하면 fullUr" http://www.example.com/foo/bar "가됩니다.

몇 달 후 코드를 정리하고 필드를 알파벳순으로 정렬했습니다 (필드가 훨씬 더 큰 목록의 일부이므로 문제를 알지 못합니다). 당신은 :

class ScopeMonitor
{
    static string firstPart= "http://www.example.com/";
    static string fullUrl= firstPart + urlFragment;
    static string urlFragment = "foo/bar";
}

귀하의 fullUrl값은 지금은 그냥 "이다 http://www.example.com/ "이후 urlFragment시간에 초기화되지 않은 fullUrl것을 한 세트. 안좋다. 따라서 초기화를 처리하기 위해 정적 생성자를 추가합니다.

class ScopeMonitor
{
    static string firstPart= "http://www.example.com/";
    static string fullUrl;
    static string urlFragment = "foo/bar";

    static ScopeMonitor()
    {
        fullUrl= firstPart + urlFragment;

    }
}

이제 필드의 순서에 관계없이 초기화가 항상 정확합니다.


1. 클래스의 정적 멤버에만 액세스 할 수 있습니다.

이유 : 정적이 아닌 멤버는 오브젝트 인스턴스에 고유합니다. 정적 생성자가 비 정적 멤버에서 작동하도록 허용되면 모든 개체 인스턴스의 변경 사항이 반영되므로 실용적이지 않습니다.

2. 정적 생성자에는 매개 변수가 없어야합니다.

이유 : CLR에 의해 호출되므로 아무도 매개 변수를 전달할 수 없습니다. 3. 하나의 정적 생성자 만 허용됩니다.

이유 : 오버로딩은 정적 생성자에서는 불가능한 메소드 / 생성자 정의 측면에서 두 메소드가 달라야합니다.

4. 액세스 수정자가 없어야합니다.

이유 : 정적 생성자에 대한 동일한 호출은 객체가 아닌 CLR에 의해 수행되므로 액세스 수정자를 가질 필요가 없습니다.


정적 생성자를 사용하여 정적 필드를 초기화 할 수 있습니다. 해당 필드가 사용되기 전에 결정되지 않은 시간에 실행됩니다. Microsoft의 설명서와 많은 개발자들은 유형의 정적 생성자가 상당한 오버 헤드를 유발한다고 경고합니다.
성능을 극대화하려면 정적 생성자를 피하는 것이 가장 좋습니다.
업데이트 : 동일한 클래스에서 두 개 이상의 정적 생성자를 사용할 수는 없지만 (최대) 하나의 정적 생성자와 함께 다른 인스턴스 생성자를 사용할 수 있습니다.


왜 그리고 언제 정적 생성자를 만들까요?

정적 생성자를 사용하는 특정 이유 중 하나 는 'super enum'클래스를 만드는 것입니다. 다음은 (간단하고 고안된) 예입니다.

public class Animals
{
    private readonly string _description;
    private readonly string _speciesBinomialName;

    public string Description { get { return _description; } }
    public string SpeciesBinomialName { get { return _speciesBinomialName; } }

    private Animals(string description, string speciesBinomialName)
    {
        _description = description;
        _speciesBinomialName = speciesBinomialName;
    }

    private static readonly Animals _dog;
    private static readonly Animals _cat;
    private static readonly Animals _boaConstrictor;

    public static Animals Dog { get { return _dog; } }
    public static Animals Cat { get { return _cat; } }
    public static Animals BoaConstrictor { get { return _boaConstrictor; } }

    static Animals()
    {
        _dog = new Animals("Man's best friend", "Canis familiaris");
        _cat = new Animals("Small, typically furry, killer", "Felis catus");
        _boaConstrictor = new Animals("Large, heavy-bodied snake", "Boa constrictor");
    }
}

다른 열거 형과 매우 유사하게 (구문 모양으로) 사용합니다.

Animals.Dog

일반 enum정보에 비해이 정보 의 장점은 관련 정보를 쉽게 캡슐화 할 수 있다는 것입니다. 한 가지 단점은 switch명령문에 이러한 값을 사용할 수 없다는 것입니다 (상수 값이 필요하기 때문).


정적 생성자

정적 수정자를 사용하여 선언 된 생성자는 정적 생성자입니다. 정적 생성자는 정적 데이터를 초기화하거나 클래스 수명주기에서 한 번만 수행해야하는 특정 작업을 수행하는 데 사용됩니다. 정적 생성자는 클래스에서 실행할 첫 번째 코드 블록입니다. 정적 생성자는 클래스의 수명주기에서 한 번만 실행됩니다. 자동으로 호출됩니다. 정적 생성자는 매개 변수를 사용하지 않습니다. 액세스 지정자가 없습니다. 직접 호출되지 않습니다.


정적 생성자는 클래스가 처음 참조되는 즉시 정적 데이터 멤버를 초기화하는 데 사용되는 반면 인스턴스 생성자는 키워드로 해당 클래스의 인스턴스를 작성하는 데 사용됩니다.

출처 : http://www.c-sharpcorner.com/article/static-constructor-in-C-Sharp-and-their-usages/


using System;
namespace Constructor
{
class Test
{
//Declaration and initialization of static data member 
private static int id = 5;
public static int Id
{
get
{
return id;
}
}
public static void print()
{
Console.WriteLine("Test.id = " + id);
}
static void Main(string[] args)
{
//Print the value of id 
Test.print();
}
}
}

In the above example, static data member <id> is declared and initialized in same line. So if you compile and run this program your output would look similar to this :

Test.id = 5

Lets create one more class similar to class Test but this time the value of its static data member would depend on the value of static data member <id> of class Test.id.

//File Name : Test1.cs
using System;
namespace Constructor
{
class Test1
{
private static int id ;
//Static constructor, value of data member id is set conditionally here. 
//This type of initialization is not possible at the time of declaration.
static Test1()
{
if( Test.Id < 10 )
{
id = 20;
}
else
{
id = 100; 
}
Console.WriteLine("Static<Class> Constructor for Class Test1 Called..");
}
public static void print()
{
Console.WriteLine("Test1.id = " + id);
}
static void Main(string[] args)
{
//Print the value of id 
Test1.print();
}
}
}

As you can see in the above static constructor, static data member <id> is initialized conditionally. This type of initialization is not possible at the time of declaration. This is where static constructor comes in picture

참고 URL : https://stackoverflow.com/questions/4506990/what-is-the-use-of-static-constructors

반응형