설명할 내용
1. 참조자
2. class 에서의 정적(static)메서드 및 인스턴스 메서드
3. 오버라이딩
4. 오버로드 [ 생성자, 메서드 ]
1. 참조자
C# 에선 & 대신 ref를 쓴다.
참조자랑 동일한 기능
using System;
class Program
{
int Swap_x = 0;
int Swap_y = 0;
// Swap 메서드는 인스턴스 메서드로 유지
public void Swap(ref int x, ref int y)
{
Swap_x = x;
Swap_y = y;
}
// Main 메서드를 static으로 선언
static void Main()
{
Program p = new Program(); // Program 클래스의 인스턴스 생성
int i = 1, j = 2;
p.Swap(ref i, ref j); // 인스턴스를 통해 Swap 메서드 호출
Console.WriteLine($"{p.Swap_x} {p.Swap_y}"); // "2 1"
i = 99;
j = 222;
p.Swap(ref i, ref j); // 인스턴스를 통해 Swap 메서드 호출
Console.WriteLine($"{p.Swap_x} {p.Swap_y}"); // "222 99"
}
}
2. class 에서의 정적(static)메서드 및 인스턴스 메서드
Class 내부에서 variable area( class 변수 선언구간 ) 에서
static 메서드는 static 으로 선언된 변수만 접근이 가능하다.
반대로 instance 메서드는 static + instance 변수 둘다 접근이 가능
생성자에서도 둘다 접근
using System;
class Entity
{
static int s_nextSerialNo;
int _serialNo;
public Entity()
{
_serialNo = s_nextSerialNo++;
}
public int GetSerialNo()
{
return _serialNo;
}
public static int GetNextSerialNo()
{
return s_nextSerialNo;
// return _serialNo; <- 이렇게 static member 함수에서 static member variable 이 아닌 member variable은 접근이 불가능하다
}
public static void SetNextSerialNo(int value)
{
s_nextSerialNo = value;
}
static void Main()
{
Entity.SetNextSerialNo(1000);
Entity e1 = new Entity();
Entity e2 = new Entity();
Console.WriteLine(e1.GetSerialNo()); // Outputs "1000"
Console.WriteLine(e2.GetSerialNo()); // Outputs "1001"
Console.WriteLine(Entity.GetNextSerialNo()); // Outputs "1002"
}
}
3. 오버라이딩
코드 설명 :
사용할 수식을 정하고, 해당 수식의 변수값 x,y, ... 에 값을 대입해 계산하는 기능을 합니다.
using System;
using System.Collections.Generic;
class Program
{
public abstract class Expression
{
public abstract double Evaluate(Dictionary<string, object> vars);
}
public class Constant : Expression
{
double _value;
public Constant(double value)
{
_value = value;
}
public override double Evaluate(Dictionary<string, object> vars)
{
return _value;
}
}
public class VariableReference : Expression
{
string _name;
public VariableReference(string name)
{
_name = name;
}
public override double Evaluate(Dictionary<string, object> vars)
{
object value = vars[_name] ?? throw new Exception($"Unknown variable: {_name}");
return Convert.ToDouble(value);
}
}
public class Operation : Expression
{
Expression _left;
char _op;
Expression _right;
public Operation(Expression left, char op, Expression right)
{
_left = left;
_op = op;
_right = right;
}
public override double Evaluate(Dictionary<string, object> vars)
{
double x = _left.Evaluate(vars);
double y = _right.Evaluate(vars);
switch (_op)
{
case '+': return x + y;
case '-': return x - y;
case '*': return x * y;
case '/': return x / y;
default: throw new Exception("Unknown operator");
}
}
}
// Main 메서드를 static으로 선언
static void Main()
{
Expression e = new Operation( // 'x' '*' new Operation
new VariableReference("x"),
'*',
new Operation( // 'y' '+' '2'
new VariableReference("y"),
'+',
new Constant(2)
)
);
//// 초기값을 지정해서 dictionary 생성하는 방법
// Dictionary<string, object> vars = new Dictionary<string, object>
// {
// {"key1", "value1"},
// {"key2", 123}
// };
Dictionary<string, object> vars = new Dictionary<string, object>(); //
vars["x"] = 3;
vars["y"] = 5;
Console.WriteLine(e.Evaluate(vars)); // "21"
vars["x"] = 1.5;
vars["y"] = 9;
Console.WriteLine(e.Evaluate(vars)); // "16.5"
}
}
4. 오버로드 [ 생성자, 메서드 ]
using System;
using System.Collections.Generic;
class OverloadingExample
{
public int x,y;
// 생성자 오버로딩
public OverloadingExample(int param_x, int param_y)
{
Console.WriteLine("class 생성자 호출 1111");
(x, y) = (param_x, param_y);
}
public OverloadingExample(int param_x)
{
Console.WriteLine("class 생성자 호출 2222");
x = param_x;
y = 0;
}
public OverloadingExample()
{
Console.WriteLine("class 생성자 호출 3333");
x = 0;
y = 0;
}
// 스태틱 메서드 오버로딩
static void F() => Console.WriteLine("F()");
static void F(object x) => Console.WriteLine("F(object)");
static void F(int x) => Console.WriteLine("F(int)");
static void F(double x) => Console.WriteLine("F(double)");
static void F<T>(T x) => Console.WriteLine($"F<T>(T), T is {typeof(T)}");
static void F(double x, double y) => Console.WriteLine("F(double, double)");
public static void UsageExample()
{
F(); // Invokes F()
F(1); // Invokes F(int)
F(1.0); // Invokes F(double)
F("abc"); // Invokes F<T>(T), T is System.String
F((double)1); // Invokes F(double)
F((object)1); // Invokes F(object)
F<int>(1); // Invokes F<T>(T), T is System.Int32
F(1, 1); // Invokes F(double, double)
}
static void Main()
{
var ins_1 = new OverloadingExample(1,3);
Console.WriteLine($"ins member var : {ins_1.x}, {ins_1.y}");
var ins_2 = new OverloadingExample(1);
Console.WriteLine($"ins member var : {ins_2.x}, {ins_2.y}");
var ins_3 = new OverloadingExample();
Console.WriteLine($"ins member var : {ins_3.x}, {ins_3.y}");
UsageExample();
}
}
'언어 정리 > C# 개념 및 lib' 카테고리의 다른 글
제네릭 클래스, Nullable(?), IEnumerator(이터레이터) (1) | 2024.01.23 |
---|---|
vscode with c# in wsl (1) | 2024.01.23 |
구조체, 인터페이스, 열거형(enum), 튜플, 네임드튜플, 딕셔너리, Nullable (0) | 2024.01.09 |
상속과 다형성 (1) | 2024.01.09 |
생성자 (0) | 2024.01.09 |
댓글