[C#] as/is/this/base

Running boy·2023년 8월 6일
0

컴퓨터 공학

목록 보기
7/36

as

명시적 형변환에 사용되는 키워드이다.

형변환이 가능하면 변환된 인스턴스를 반환하고 그렇지 않으면 null을 반환한다.

참조 형식에만 사용 가능하다.

+) C# 2에서 Nullable 형식이 추가되었고 as 연산을 지원한다. (Nullable 형식은 값 형식 구조체이다.)

Dog dog = new Dog();
Animal animal = (Animal)dog; //(Animal)을 생략하고 암시적 형변환도 가능
bool isAnimal = animal != null; // True
Dog dog = new Dog();
Animal animal = dog as Animal;
bool isAnimal = animal != null; // True

위와 같이 특수화 타입에서 일반화 타입으로 형변환 할 경우 기존 명시적 형변환 형식과 as 연산자의 결과값은 같다.

하지만 아래와 같이 일반화 타입에서 특수화 타입으로 형변환 할 경우 as 연산자를 사용하지 않으면 런타임 에러가 발생할 수 있다.

Animal animal = new Animal();
Dog dog = (Dog)animal; // 런타임 에러 발생, 컴파일은 가능
bool isDog = dog != null;
Animal animal = new Animal();
Dog dog = animal as Dog;
bool isDog = dog != null; // False

정리하면 형변환이 실패했을 때, ()를 사용해 명시적 형변환을 시도했을 경우에는 런타임 에러가 발생하지만 as 연산자를 사용할 경우 에러가 발생하지 않고 null을 반환한다.


is

형변환의 가능성 여부를 bool값으로 반환한다.

값 형식, 참조 형식 모두 사용 가능하다.

int i = 0;
if (i is Dog) // 에러가 발생하지 않는다. 다만 컴파일러가 경고는 해준다.
{
    ...
}

C# 7.0부터 is 연산자를 as 연산자처럼 사용할 수 있게 됐다.

Dog dog = new Dog();
if (dog is Animal animal) // is 연산의 결과가 True면 animal에 인스턴스 할당
{
    ...
}

this

클래스 내부에서 인스턴스 자신을 가리키는 키워드이다.

아래와 같이 클래스 멤버와 매개변수명이 같을 때 this로 명시하지 않을 경우 매개변수를 가리키게 된다.

class Dog
{
    string name;

    public Dog(string name)
    {
        //this.name = name;
        name = name; // 첫번째 name과 두번째 name 전부 매개변수를 가리킨다.
    }
}

자신의 생성자를 가리킬 때 this 키워드를 사용할 수 있다.

class Dog
{
    public string name { get; private set; }

    public Dog() : this("Siberian Husky")
    {

    }

    public Dog(string name)
    {
        this.name = name;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Dog husky = new Dog();
        Dog corgi = new Dog("Welsh Corgi");

        Console.WriteLine(husky.name);
        Console.WriteLine(corgi.name);
    }
}

// 출력: 
// Siberian Husky
// Welsh Corgi

생성자가 여러개인 경우 this 키워드로 다른 생성자를 호출할 수 있다.

이를 통해 코드의 중복을 피할 수 있다.


this를 컴파일러는 어떻게 인식하는가

C# 컴파일러는 인스턴스 메서드 호출 시 this를 첫번째 인자로 넘겨준다.

class Dog
{
    string name;

    public void Bark()
    {
        Console.WriteLine(this.name + " Bark!");
    }
}
Dog dog = new Dog();
dog.Bark();

위 코드를 실행하면 컴파일러는 코드를 아래와 같이 변환한다.

class Dog
{
    string name;

    public void Bark(Dog this) // 첫번째 매개변수로 자기자신을 받는다.
    {
        Console.WriteLine(this.name + " Bark!");
    }
}
Dog dog = new Dog();
dog.Bark(dog); // 첫번째 인자로 자기자신을 넘긴다.

만약 메서드를 정적으로 정의한다면 인스턴스 멤버에 접근할 수 없기 때문에 자연스럽게 this 키워드도 사용할 수 없다.

모든 인스턴스 메서드는 자기자신을 인자로써 받기 때문에(즉 받는 인자가 반드시 1개씩 늘어나기 때문에) 멤버에 접근하지 않는 메서드는 정적 메서드로 정의하는 것이 성능상 유리할 수 있다. (하지만 크게 차이나진 않는다.)


base

부모 클래스 인스턴스를 가리키는 키워드이다.

this와 가리키는 대상이 다를 뿐 사용 패턴은 유사하다.

class Animal
{
    public int size { get; private set; }

    public Animal(int size)
    {
        this.size = size;
    }
}

class Dog : Animal
{
    public string name { get; private set; }

    public Dog() : this("Siberian Husky")
    {

    }

    public Dog(string name) : this(name, 10)
    {
        
    }

    public Dog(string name, int size) : base(size)
    {
        this.name = name;
    }
}

참고 자료
시작하세요! C# 10 프로그래밍 - 정성태

profile
Runner's high를 목표로

0개의 댓글