C#/.NET(17): static(1)
static 은 편리하다.
유니티를 공부했을 때, 예를 들어 점수를 기록하여 전광판에 출력하는 기능을 구현할 때 유용하게 사용했던 기억이 있다.
뿐만 아니라, 학생들이 객체 참조를 통해 메소드나 변수에 접근하는 걸 무척이나 어려워하기 때문에, 이러한 복잡한 참조 없이 다이렉트로 스태틱 멤버에 접근하게 하여 값을 가져오게 하거나 쓰게 하는 방법으로 프로젝트를 지도했던 경우도 많다.
하지만, 이 static은 프로그램이 시작되면 별도의 static 영역에 저장되어 프로그램이 종료될 때까지 유지되는 특징을 가지고 있다.
그러한 이유로, 예를 들어 FPS게임처럼 한명의 유저당 고유의 스코어 값을 갖는 경우 하나의 static 멤버로 스코어를 관리할 수는 없다. 왜냐하면, 이 static 멤버는 프로그램이 종료될 때까지 메모리에서 사라지지 않기 때문에 값이 그대로 유지 되기 때문에, 여러명의 유저가 같은 스코어 값을 갖게 되어버린다.
static 의 용도
-
용도1: static class와 static member를 정의하는데 사용
-
용도2: 매번 명시적으로 이름을 지정할 필요 없이 정적 멤버를 참조하는데 using static 지시문에 사용
[용도1 - 예시 코드]
static 멤버에 연산을 하는 경우, static 멤버를 직접 호출해야 한다.
아래는 내가 초보일 때 많이 하던 실수이면서, 가끔 생각없이 저지르는 실수이기도 하다.
using System;
using System.Collections.Generic;
namespace Static
{
class Box
{
public static int MaxCount = 50; // static 멤버
private List<string> _elements = new List<string>();
public void add(string element)
{
if(_elements.Count < MaxCount)
{
_elements.Add(element);
}
}
}
internal class Program
{
static void Main(string[] args)
{
var obj1 = new Box();
obj1.add("Hello");
var obj2 = new Box();
//var invalidMaxCount = obj2.MaxCount; // non static 클래스에서 static 멤버를 호출할 수 없음
var validMaxCount = Box.MaxCount; // static 멤버 호출
Console.WriteLine(validMaxCount); // 50
validMaxCount++;
Console.WriteLine(Box.MaxCount); // 50
Box.MaxCount++;
Console.WriteLine(Box.MaxCount); // 51
}
}
}
static 은 멤버 뿐만 아니라 아래와 같이 메소드에도 지정할 수 있다.
using System;
using System.Collections.Generic;
namespace Static
{
class Box
{
public static int MaxCount = 50; // static 멤버
private List<string> _elements = new List<string>();
public void add(string element)
{
if(_elements.Count < MaxCount)
{
_elements.Add(element);
}
}
public int GetCurrentCount_1()
{
return _elements.Count;
}
public static int GetCurrentCount_2()
{
return MaxCount; // 선언된 클래스 안에서 static 멤버 호출
}
}
internal class Program
{
static void Main(string[] args)
{
var obj1 = new Box();
obj1.add("Hello");
Console.WriteLine(obj1.GetCurrentCount_1());
// Console.WriteLine(obj1.GetCurrentCount_2()); // 호출할 수 없음
Console.WriteLine(Box.GetCurrentCount_2()); // static 메소드 호출
//var obj2 = new Box();
////var invalidMaxCount = obj2.MaxCount; // non static 클래스에서 static 멤버를 호출할 수 없음
//var validMaxCount = Box.MaxCount; // static 멤버 호출
//Console.WriteLine(validMaxCount); // 50
//validMaxCount++;
//Console.WriteLine(Box.MaxCount); // 50
//Box.MaxCount++;
//Console.WriteLine(Box.MaxCount); // 51
}
}
}
[용도2 - 예시 코드]
using (static 클래스)를 사용하기 전, 매번 static 클래스의 이름을 호출해야되는 번거로움이 있다.
using System;
namespace Static
{
// using Math 사용 전
public static class Caluculator
{
public static double Sqaure(double side)
{
return Math.Pow(side, 2);
}
public static double CircleArea(double radius)
{
return Math.PI * Math.Pow(radius, 2);
}
}
}
하지만, using (static 클래스)를 통해 멤버 호출 시, 코드의 길이를 줄일 수 있다.
using System;
using static System.Math; // using static 클래스 포함
namespace Static
{
public static class Caluculator
{
public static double Sqaure(double side)
{
return Pow(side, 2);
}
public static double CircleArea(double radius)
{
return PI * Pow(radius, 2);
}
}
}
댓글남기기