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

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...