명시적 형변환에 사용되는 키워드이다.
형변환이 가능하면 변환된 인스턴스를 반환하고 그렇지 않으면 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을 반환한다.
형변환의 가능성 여부를 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로 명시하지 않을 경우 매개변수를 가리키게 된다.
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 키워드로 다른 생성자를 호출할 수 있다.
이를 통해 코드의 중복을 피할 수 있다.
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개씩 늘어나기 때문에) 멤버에 접근하지 않는 메서드는 정적 메서드로 정의하는 것이 성능상 유리할 수 있다. (하지만 크게 차이나진 않는다.)
부모 클래스 인스턴스를 가리키는 키워드이다.
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 프로그래밍 - 정성태