레이블이 시샵인 게시물을 표시합니다. 모든 게시물 표시
레이블이 시샵인 게시물을 표시합니다. 모든 게시물 표시

2022년 1월 29일 토요일

C# 연산자 오버로딩, Operator Overloading, public static ~ operator(C#동영상, 닷넷동영상교육, C#학원, 자바학원, C#동영상, WPF학원, WPF교육)

 C# 연산자 오버로딩,  Operator Overloading,  public static ~ operator(C#동영상, 닷넷동영상교육, C#학원, 자바학원, C#동영상, WPF학원, WPF교육)


http://ojc.asia/bbs/board.php?bo_table=LecCsharp&wr_id=403 


C# 연산자 오버로딩, Operator Overloading, public static ~ operator(C#동영상, 닷넷동영상교육)

C# 연산자 오버로딩, Operator Overloading, public static ~ operator(C#동영상, 닷넷동영상교육)연산자 오버로딩Operator Overloading실습 : VS 2022연산자 오버로딩(Operator Overloading)연산자 오버로딩이란 +, -와 같은

ojc.asia

https://www.youtube.com/watch?v=XC3f8CnY6yk&list=PLxU-iZCqT52DJyR6gqJy0MCL8RiTVXdos&index=14 





연산자 오버로딩

Operator Overloading 


실습 : VS 2022





연산자 오버로딩(Operator Overloading)


  • 연산자 오버로딩이란 +, -와 같은 연산자들을 용도에 맞게 다시 의미, 기능을 부여하여 작동하도록 한 것인데, 메소드 오버로딩에서 메소드의 인자개수나 타입을 변형해서 같은 메소드를 여러개 정의하는 것과 비슷하게 연산자는 같지만 받아들이는 피연산자의 형식이 다르게해서 연산자의 의미, 기능을 여러 개 정의하는 것이다. 
  • public static ~ operator 키워드를 사용한다.



다음과 같은 A 클래스가 있다고 하자.


public class A{

public int val;

}


A a1 = new A();   a1.val=1;

A a2 = new A();   a2.val=2;


//객체를 더할수는 없다. 오류!!

A a3 = a1 + a2;  


위 예제를 다음과 같이 고쳐 보자.


namespace OperatorOverload1

{

public class A

{

public int val;

public static A operator +(A a1, A a2)

{

A a3 = new A();

a3.val = a1.val + a2.val;

return a3;

}

}


class Test

{

static void Main()

{

A a1 = new A(); a1.val = 1;

A a2 = new A(); a2.val = 2;

A a3 = a1 + a2;


Console.WriteLine("a1 + a2 = {0}", a3.val);

}

}

}


[다음 예제를 보자]


namespace OperatorOverload1

{

public class A1

{

public int val;

//아래의 함수는 A1, A2에서는 정의가 가능하며 A3에서는 불가

public static A3 operator +(A1 a1, A2 a2)

{

A3 a3 = new A3();

a3.val = a1.val + a2.val;

return a3;

}

}


public class A2 { public int val; }

public class A3 { public int val; }


class Test

{

static void Main()

{

A1 a1 = new A1(); a1.val = 1;

A2 a2 = new A2(); a2.val = 2;

A3 a3 = a1 + a2;

Console.WriteLine("a1 + a2 = {0}", a3.val);

}

}

}



C#에서 오버로딩 할 수 있는 연산자.


단항 연산자 ::: +, -, !,  ~, ++, --, true, false

이항 연산자 ::: +, -, *, /, %, &, |, <<, >>

비교 연산자 ::: ==, !=, <, >, <= , >=


  • true와 false를 오버로딩 하면 클래스, 객체를 bool 표현식에서 사용 할 수 있다.
  • += 같은 배정 연산자는 오버로딩 할 수 없지만 +연산자를 오버로딩 함으로써 +=을 오버로딩 한 것과 같은 효과를 나타낸다. 
  • =(등호)는 오버로딩 할 수 없는데 이 연산자는 기능을 바꿀 필요가 없는 것이다. 
  • &&와 ||역시 오버로딩 할 수 없는데 &, |를 오버로딩 하여 구현하면 된다. 
  • < 와 >의 경우 반드시 쌍으로 오버로딩 해야 한다. 즉 < 를 오버로딩 했을 때 >도 반드시 오버로딩 해야 한다. 비교연산자를 오버로딩 할 때는 한 연산자에서 다른 연산자를 호출하여 처리할 수도 있다.
  • true 와 false의 경우도 반드시 쌍으로 오버로딩 해야 한다. 


public class A{

public int val;

public static bool operator > (A op1, Aop2) {

return (op1.val > op2.val);
}


public static bool operator < (A op1, Aop2) {

return !(op1 > op2);

}

}


  • ==와 != 연산자에 대해서는 위의 경우 처럼 사용이 가능하나 Object.Equals()와 Object.GetHashCode()도 재정의 하는 경우가 많이 있다. 즉 ==를 재정의 하는 부분에서 Equals 메소드도 재정의 함으로써 사용자가 == 또는 Equals() 어느 것으로 비교하든지 같은 결과가 나타나게 할 수 있다. 


[예제]

namespace ConsoleApplication2

{

    public class A

    {

        public int val;

        public static bool operator ==(A op1, A op2) { return (op1.val == op2.val); }

        public static bool operator !=(A op1, A op2) { return !(op1 == op2); }


        public static bool operator >(A op1, A op2) { return (op1.val > op2.val); }


        public static bool operator <(A op1, A op2) { return (op1.val < op2.val); }

        //op1과 op2가 같아도 true이므로 위의꺼로

        //public static bool operator < (A op1, A op2) { return !(op1.val > op2.val); }  


        public override bool Equals(object op1)

        {

            return val == ((A)op1).val;

        }

        //GetHashCode 는 개체의 상태에 기반한 고유한 int 값을 얻는데 사용 한다.

        //Equals 메서드를 재정의했다면, 반드시 GetHashCode메서드에 대해서도 재정의를 해줘야 한다

        //컴파일러는 Equals만 재정의한 경우 경고 메시지를 표시한다.

        //모든 컬렉션에서는 두 객체가 동일한지 알기위해 GeHashCode를 확인하기때문

        public override int GetHashCode() { return this.GetHashCode(); }


        static void Main()

        {

            A op1 = new A(); op1.val = 1;

            A op2 = new A(); op2.val = 2;

            Console.WriteLine("op1 = op2 = {0}", op1 == op2);

            Console.WriteLine("op1 = op2 = {0}", op1.Equals(op2));

            Console.WriteLine("op1 > op2 = {0}", op1 > op2);

            Console.WriteLine("op1 < op2 = {0}", op1 < op2);

        }

    }


}


#연산자오버로딩, #OperatorOverloading, #닷넷, #시샵, #닷넷동영상, #시샵동영상, #닷넷교육, #닷넷학원, #시샵학원, #시샵연산자,
연산자오버로딩, OperatorOverloading, 닷넷, 시샵, 닷넷동영상, 시샵동영상, 닷넷교육, 닷넷학원, 시샵학원, 시샵연산자

2020년 7월 22일 수요일

1-6. C# 자료형(Value Type, Reference Type)

1-6. C# 자료형(Value Type, Reference Type)

http://ojc.asia/bbs/board.php?bo_table=LecCsharp&wr_id=382

C#의 데이터 타입은 실제 그 값을 가지고 있는 Value-Type과 가지고 있는 것이 값이 아니고 무언가를 참조하는 변수(C언어의 포인터 변수)인 Reference-Type 두 가지로 구분한다.

CTS

CTS는 닷넷 프레임워크에서 동작하는 모든 프로그래밍 언어(C#, VB.Net, J#)들이 똑같은 데이터형식을 사용하도록 해주는 것이다. (System.Int32라는 클래스는 CTS에서 제공하는 int형인데 이것은 닷넷의 어떠한 개발언어에서도 사용이 가능하다.)

모든 데이터형식들은 기본적으로 객체에서 파생되었으며 Value-Type은 객체 형식을 포장 (sealing)해 놓은 개념이다.

Value-Type, Reference-Type

Value-Type

CTS 에서는 value type과 reference type 을 지원하는데 value type 변수들은 데이터를 직접 가지고 있다. 예를 들어 int i=10 이라고 쓰면 변수 i에는 10이 직접 들어 있는 것이다. int j=i 라고 하면 i의 값이 j에 복사되어 들어 가는 것이다. Value-Type은 Built-in Type과 User-Defined Type 두 가지가 있는데 int, long, float, double 등은 Built-in Type이고 struct, enum 등은 User-Defined ㅍValue Type이다.

기본 제공 데이터 형식 중 string 데이터 형식은 예외적으로 참조 형식이다.

Value-Type은 스택에 할당된 메모리에 값을 저장하는데 아래 경우에는 스택영역에 4바이트 공간을 확보 후 100이 저장된다.

void Sum {

int i = 100;

……

}

i 변수가 정의된 Sum메소드의 실행이 종료되어 변수가 범위를 벗어나면 값이 스택에서 삭제된다.

즉 스택을 사용하면 효율적이고 성능 상 장점도 있지만 값 형식의 수명이 제한되므로 서로 다른 클래스 간에 데이터를 공유하는 데는 적합하지 않다.

[정수형]

sbyte System.Sbyte 8 -128~127

byte System.Byte 8 0~255

short System.Int16 16 -32,768~32,767

ushort System.UInt16 16 0~65,535

int System.Int32 32 -2,147,483,648 ~2,147,483,647

uint Systen.UInt32 32 0~4,294,967,295

long System.Int64 64 -(2^63) ~ 2^63-1

ulong System.UInt64 64 0~ 2^64-1

[실수형]

float System.Single 32 1.5x10^-46 ~3.4x10^38

double System.Double 64 5.0x10^-324 ~1.7x10^308

decimal System.Decimal 128 1.0x10^-28 ~7.9x10^28

기타

char System.UInt16 16 유니코드 1 자

bool System.Int32 1 0 또는 1

[Boolean형]

boolean type이 가질 수 있는 값은 true와 false 예) bool b = true --> true 는 1 과는 다르며 마찬가지로 false는 0과는 다르다. (C 에서는 TRUE, FALSE를 #define을 통해 정의하여 사용했었는데 이는 정수를 암묵적으로 boolean형으로 사용한 것이다.) true와 false로 산술 연산을 할 수 없으며 오로지 논리 연산자를 가진 수식에 대해서만 사용 가능하다.

[Value Type의 초기화]

- 로컬변수는 반드시 초기화가 되어야 한다.

int onj; //로컬변수로 선언되었다면 이 변수는 사용 전 반드시 초기화 돼야 한다.

onj = new int(); // Invoke default constructor for int type.

onj = 0; // Assign an initial value, 0 in this example.

위 두 문장은 같은 결과를 나타내며 다음처럼 한 줄로 표시하면 된다.

int onj = 0;

Reference-Type

데이터를 직접 저장하는 것이 아니라 레퍼런스(참조값)를 저장한다.(Store references to their data) 그러므로 두 개의 레퍼런스형 변수는 같은 데이터(오브젝트)를 가리키는 것이 가능하다.( Two reference variables can reference same object). 물론 같은 것을 서로 참조할 수 있으므로 한 쪽에서 변경을 하면 다른 쪽에서 변경을 안 했더라도 나중에 값을 꺼내 보면 바뀌어져 있다.(Operations on one can affect another)

​

클래스 또는 배열의 인스턴스와 같은 참조 형식은 힙(Heap)이라는 다른 메모리 영역에 할당된다. 아래 예문에서는 배열을 구성하는 5개의 정수에 필요한 공간이 힙에 할당된다.

void Sum {

int[] numbers = new int[5];

……

}

이때 힙에 할당된 메모리는 메소드가 종료 되더라도 힙에 반환되지 않으며, C#의 가비지 수집 시스템에서 이 메모리가 더 이상 필요하지 않다고 판단할 때에만 회수된다. 참조 형식을 선언하면 오버헤드가 커지지만 참조 형식은 다른 클래스에서 액세스할 수 있다는 장점이 있다.

[Reference Type 예제]

using System;

namespace ConsoleApplication1

{

class Rtype

{

public object Value;

}

class Program

{

static void Main(string[] args)

{

Rtype a = new Rtype ();

Rtype b = new Rtype ();

a.Value = 1; b = a; //a가 참조하는 것을 b도 참조한다.

Console.WriteLine(a.Value); Console.WriteLine(b.Value);

b.Value = 2;

Console.WriteLine(a.Value); Console.WriteLine(b.Value);

}

}

}

[결과]

1

1

2

2

(C#교육동영상)C# ADO.NET 실습 ODP.NET/ODAC 설치 오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원

  (C#교육동영상)C# ADO.NET 실습  ODP.NET/ODAC 설치  오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원 https://www.youtube.com/watch?v=qIPU85yAlzc&list=PLxU-i...