해당 함수를 사용하면 자식 오브젝트 뿐만 아니라 본인 오브젝트에 포함된 컴포넌트도 가져옵니다. 따라서 사용시에 주의해서 사용해야 합니다.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/* Smf : Stat Modifier Feature */
public class Smf : MonoBehaviour
{
   public string itemName;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Consume : MonoBehaviour
{
    public Smf[] smfList;
    
    void Start()
    {
        smfList = gameObject.GetComponentsInChildren<Smf>();
    }
}

 

블로그 이미지

NIA1995

,

using 키워드에는 널리 알려진 네임스페이스에서 정의된 형식을 가져오는 기능 이외에도 다양한 기능이 존재합니다. 공식 문서를 살펴보며 간단하게 살펴보겠습니다.

 

1. 개체가 삭제될 끝에서 범위를 지정 /* docs.microsoft.com/ko-kr/dotnet/api/system.idisposable?view=net-5.0 */

   1) 이 인터페이스의 주요 용도는 관리되지 않는 리소스를 해제하는 것입니다.

   2) 가비지 수집기는 창 핸들 또는 열린 파일 및 스트림과 같은 관리 되지 않는 리소스에 대해 알지 못합니다.

   3) 따라서 가비지 수집기와 함께 관리 되지 않는 리소스를 명시적으로 해제합니다.

 

한번 더 설명하면 C#에서는 가비지 콜렉터가 작동하는데 항상 만능은 아닙니다. 따라서 명시적으로 리소스를 해제해야 할 때 using 키워드를 사용하여 IDisposable을 적용할 수 있습니다.

 

void ReadData() {
            using(BinaryReader binaryReader = new BinaryReader(new FileStream(src, FileMode.Open))) {
                int intNum = binaryReader.ReadInt32();
                float floatNum = binaryReader.ReadSingle();
                string stringData = binaryReader.ReadString();
                bool boolData = binaryReader.ReadBoolean();
                
                /* binaryReader.Close()가 자동 호출 */
            }
        }

 

위의 코드와 같이 using 문을 사용하면 자칫 실수하고 넘어갈 수도 있는 binaryReader의 리소스를 자동으로 해제할 수 있습니다.

 

2. 네임스페이스의 별칭 제작

 

간단하게 기존 네임 스페이스의 별칭을 제작하여 사용할 수 있는 기능입니다.

 

using PD = PersonalData;

class PersonalData
{
	…….
}

 

위의 코드와 같이 using 문을 사용하면 PersonalData 대신 PD로도 클래스에 접근이 가능합니다.

 

3. using static 지시문 /* docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/using-static */

   1) 일반적으로 정적 멤버를 호출하기 위해 멤버의 이름과 함께 형식 이름을 사용합니다.

   2) 이러한 정적 멤버의 호출이 반복되는 경우 코드가 복잡하고 난해해질 수 있습니다.

   3) 이때, using static 키워드를 사용하면 깔끔한 코드를 생성할 수 있습니다.

 

using System;

public class Circle
{
   public Circle(double radius)
   {
      Radius = radius;
   }

   public double Radius { get; set; }

   public double Diameter
   {
      get { return 2 * Radius; }
   }

   public double Circumference
   {
      get { return 2 * Radius * Math.PI; }
   }

   public double Area
   {
      get { return Math.PI * Math.Pow(Radius, 2); }
   }
}

-----------------------------------------------------

using System;
using static System.Math;

public class Circle
{
   public Circle(double radius)
   {
      Radius = radius;
   }

   public double Radius { get; set; }

   public double Diameter
   {
      get { return 2 * Radius; }
   }

   public double Circumference
   {
      get { return 2 * Radius * PI; }
   }

   public double Area
   {
      get { return PI * Pow(Radius, 2); }
   }
}

 

위의 코드와 같이 반복적인 형식 이름의 접근이 사라졌습니다. 하지만 다중으로 using static 키워드를 사용했을 경우 각 클래스에서 같은 이름의 멤버들이 존재할 수도 있으므로 주위가 필요합니다.

블로그 이미지

NIA1995

,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

using System.Runtime.Serialization.Formatters.Binary;

namespace Serialization
{
    [Serializable]
    class Playable
    {
        public string name;
        public int level;
        public long exp;

        public Playable()
        {
            name = "";
            level = 1;
            exp = 0;
        }

    }


    class Program
    {
        const string fileName = "SaveData.txt";

        static void Main(string[] args)
        {
            /* 객체 초기화 */
            Playable[] characters = new Playable[3];

            for(int i = 0; i < 3; ++i)
            {
                characters[i] = new Playable();
            }

            characters[0].name = "아라곤";
            characters[0].level = 100;
            characters[0].exp = 2000;

            characters[1].name = "레골라스";
            characters[1].level = 98;
            characters[1].exp = 1720;

            characters[2].name = "김 리";
            characters[2].level = 99;
            characters[2].exp = 1890;

            /* 직렬화 후 데이터 저장 */
            FileStream writeStream = new FileStream(fileName, FileMode.Create);

            BinaryFormatter binaryFormatter = new BinaryFormatter();
            binaryFormatter.Serialize(writeStream, characters);

            writeStream.Close();

            /* 직렬화 된 데이터 읽기 */
            FileStream readStream = new FileStream(fileName, FileMode.Open);

            BinaryFormatter binaryFormatter2 = new BinaryFormatter();

            characters = (Playable[])binaryFormatter2.Deserialize(readStream);

            for(int i = 0; i < characters.Length; ++i)
            {
                Console.WriteLine("Name : {0} \t Level : {1} \t Exp : {2} \t", characters[i].name, characters[i].level, characters[i].exp);
            }

            readStream.Close();
        }
    }
}

해당 예제에서는 직렬화가능 속성(Serialization Attribute) 속성을 사용하여 직렬화를 테스트 하였습니다. 기본적으로 이보다 더 많은 제어가 필요한 경우 ISerializable 인터페이스를 상속받아 구현할 수 있습니다. 해당 코드에서는 사용하지 않았지만 ISerializable 인터페이스를 사용하는 경우 GetObjectData() 함수를 재정의하여 데이터 직렬화를 효과적으로 진행할 수 있습니다.

블로그 이미지

NIA1995

,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace Stream
{
    class Program
    {
        static void Main(string[] args)
        {
            /* Write */
            FileStream writeStream = new FileStream("test.txt", FileMode.Create);
            StreamWriter streamWriter = new StreamWriter(writeStream);

            streamWriter.WriteLine("IZONE");
            streamWriter.WriteLine("아이즈원");

            streamWriter.WriteLine("Jo Yuri");
            streamWriter.WriteLine("조유리");

            streamWriter.WriteLine("Choi Yena");
            streamWriter.WriteLine("최예나");

            streamWriter.Close();

            /* Read */
            FileStream readStream = File.Open("test.txt", FileMode.Open);
            StreamReader streamReader = new StreamReader(readStream);

            Console.WriteLine("streamReader.BaseStream.Length : " + streamReader.BaseStream.Length);
            
            while(false == streamReader.EndOfStream)
            {
                Console.WriteLine(streamReader.ReadLine());
            }

            streamReader.Close();
        }
    }
}

FileStream을 사용한 StreamWriter, StreamReader 사용법

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace Stream
{
    class Program
    {
        static void Main(string[] args)
        {
            /* Write */
            StreamWriter streamWriter = new StreamWriter("StandAlone.txt");

            streamWriter.WriteLine("김민주");
            streamWriter.WriteLine("안유진");
            streamWriter.WriteLine("히토미");
            streamWriter.WriteLine("사쿠라");

            streamWriter.Close();

            /* Read */
            StreamReader streamReader = new StreamReader("StandAlone.txt"); ;

            while(false == streamReader.EndOfStream)
            {
                Console.WriteLine(streamReader.ReadLine());
            }

            streamReader.Close();
        }
    }
}

StreamWriter, StreamReader 단독 사용법

'프로그래밍 > 코드 정리' 카테고리의 다른 글

[C#] BitConverter 테스트  (0) 2021.04.02
[C#] 성적 정렬 프로그램  (0) 2021.03.29
[C#] 성적 입력 프로그램  (0) 2021.03.25
[C#] 우승할 달리기 선수 맞추기  (0) 2021.03.21
[C#] 성적 프로그램  (0) 2021.03.20
블로그 이미지

NIA1995

,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace BitConverter
{
    class Program
    {
        const string fileName = "BitConverter.txt";

        static void Main(string[] args)
        {
            long longValue = 1234567890123456789;
            int intValue = 100;
            string stringValue = "IZONE";

            char[] charArrayValue = stringValue.ToCharArray();

            Console.WriteLine("Default Data");
            Console.WriteLine("----------------------");
            Console.WriteLine(longValue);
            Console.WriteLine(intValue);
            Console.WriteLine(stringValue);
            Console.WriteLine();


            /* Write Start */
            Stream writeStream = new FileStream(fileName, FileMode.Create);
            
            /* Long Test */
            byte[] writeByBytes = BitConverter.GetBytes(longValue);

            Console.WriteLine("Byte Data");
            Console.WriteLine("----------------------");

            Console.Write("Byte : ");

            foreach (var item in writeByBytes)
            {
                /* 2진수 출력 0:X */
                Console.Write("{0:X2} ", item);
            }

            Console.WriteLine();

            writeStream.Write(writeByBytes, 0, writeByBytes.Length);

            /* Integer Test */
            writeByBytes = BitConverter.GetBytes(intValue);

            Console.Write("Byte : ");

            foreach (var item in writeByBytes)
            {
                Console.Write("{0:X2} ", item);
            }

            Console.WriteLine();

            writeStream.Write(writeByBytes, 0, writeByBytes.Length);

            Console.Write("Byte : ");

            /* CharArray Test */
            foreach (var item in charArrayValue)
            {
                byte[] writeByByte = BitConverter.GetBytes(item);

                writeStream.Write(writeByByte, 0, writeByByte.Length - 1);

                Console.Write("{0:X2} ", Convert.ToInt32(item));
            }

            Console.WriteLine("\n");
            writeStream.Close();
            /* Write End */


            /* Read Start */
            FileStream readStream = new FileStream(fileName, FileMode.Open);


            byte[] readBytes = new byte[sizeof(long)];

            readStream.Read(readBytes, 0, readBytes.Length);

            long readLongValue = BitConverter.ToInt64(readBytes, 0);


            readBytes = new byte[sizeof(int)];

            readStream.Read(readBytes, 0, readBytes.Length);

            int readIntValue = BitConverter.ToInt32(readBytes, 0);


            string readStringValue = "";

            readBytes = new byte[readStream.Length];

            readStream.Read(readBytes, 0, readBytes.Length);

            foreach (var item in readBytes)
            {
                readStringValue += (char)item;
            }

            Console.WriteLine("Result Data");
            Console.WriteLine("----------------------");

            Console.WriteLine(readLongValue);
            Console.WriteLine(readIntValue);
            Console.WriteLine(readStringValue);

            readStream.Close();
            /* Read End */
        }
    }
}

----------------------------------------------------
Default Data
----------------------
1234567890123456789
100
IZONE

Byte Data
----------------------
Byte : 15 81 E9 7D F4 10 22 11
Byte : 64 00 00 00
Byte : 49 5A 4F 4E 45

Result Data
----------------------
1234567890123456789
100
IZONE

'프로그래밍 > 코드 정리' 카테고리의 다른 글

[C#] StreamWriter, StreamReader  (0) 2021.04.02
[C#] 성적 정렬 프로그램  (0) 2021.03.29
[C#] 성적 입력 프로그램  (0) 2021.03.25
[C#] 우승할 달리기 선수 맞추기  (0) 2021.03.21
[C#] 성적 프로그램  (0) 2021.03.20
블로그 이미지

NIA1995

,

파일 입출력을 공부하다가 두 클래스의 함수와 프로퍼티를 나눠서 사용하는 예제를 보았는데 차이점이 있는가 궁금해서 찾아보았습니다. 결론적으로 두 클래스의 함수와 프로퍼티는 동일한 기능을 합니다.

 

단지 함수(Directory.GetCurrentDirectory, Directory.SetCurrentDirectory)와 프로퍼티(Environment.CurrentDirectory)로 나누어져 있습니다. 따라서 편하신 방법을 골라 사용하시면 될 것 같습니다.

 

string directoryPath = Directory.GetCurrentDirectory();
string environmentPath = Environment.CurrentDirectory;

Console.WriteLine("DirectoryPath : {0}", directoryPath);
Console.WriteLine("EnvironmentPath : {0}", environmentPath);

-------------------------------------------------------
DirectoryPath : D:\ConsoleProject\Test\Join\bin\Debug
EnvironmentPath : D:\ConsoleProject\Test\Join\bin\Debug

'프로그래밍 > C#' 카테고리의 다른 글

[C#] using 키워드의 다양한 사용처  (0) 2021.04.02
[C#] 직렬화(Serialization)  (0) 2021.04.02
[C#, LINQ] 내부 조인과 외부 조인  (0) 2021.03.31
[C#] Boxing과 Unboxing  (0) 2021.03.15
[C#] 값형식과 참조형식의 예시  (2) 2021.03.15
블로그 이미지

NIA1995

,

INNER JOIN

 

LINQ에서 내부 조인은 기본적으로 두 개의 데이터들 사이에서 일치하는 데이터들만 연결시켜 반환합니다. 첫 번째 데이터를 기준으로 두 번째 데이터를 equals를 사용해 비교하여 일치하는 데이터들을 모아 반환합니다.

 

var InnerJoin =
	from a in A
    	join b in B a.variables equals b.variables

 

A라는 데이터 원본에서 a라는 범위 변수를 뽑아오고, 두 번째 B라는 데이터 원본에서 b라는 범위 변수를 뽑아옵니다. 이후, equals에서 두 데이터를 비교하여 일치하는 데이터를 뽑아냅니다.

 

OUTER JOIN

 

외부 조인은 내부 조인과 달리 기준이 되는 데이터는 데이터의 일치 여부와 상관없이 모두 다 포함이 됩니다. 대신 일치하지 않는 데이터가 없는 경우에는 그 부분을 빈 값으로 처리하고, 임시 컬렉션에서 DefaultIsEmpty 연산을 통해 빈 값을 채워 줄 수 있습니다.

 

var OuterJoin =
	from a in A
    	join b in B a.variables equals b.variables into data
        from b in data.DefaultIfEmpty(new Class() { 데이터 삽입 })

 

실습

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Join
{
    struct Idol
    {
        public string name { get; set; }
        public string groupName { get; set; }

        public int age { get; set; }
        public int height { get; set; }

        public Idol(string _name, string _groupName, int _age, int _height)
        {
            name = _name;
            groupName = _groupName;
            age = _age;
            height = _height;
        }
    }

    struct Star
    {
        public string name { get; set; }
        public string team { get; set; }
 
        public int age { get; set; }
        public int height { get; set; }


        public Star(string _name, int _age, int _height, string _team = null)
        {
            name = _name;
            age = _age;
            height = _height;
            team = _team;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Idol[] Izone =
            {
                new Idol("권은비", "아이즈원", 25, 160),
                new Idol("김민주", "아이즈원", 19, 163),
                new Idol("조유리", "아이즈원", 19, 162),
                new Idol("최예나", "아이즈원", 21, 162),
                new Idol("김채원", "아이즈원", 20, 163),
                new Idol("강혜원", "아이즈원", 21, 163),
                new Idol("장원영", "아이즈원", 16, 175),
                new Idol("안유진", "아이즈원", 17, 169),
                new Idol("이채연", "아이즈원", 21, 165),
                new Idol("사쿠라", "아이즈원", 23, 163),
                new Idol("나코",   "아이즈원", 19, 150),
                new Idol("히토미", "아이즈원", 19, 158),
            };

            Star[] AKB48 =
            {
                new Star("사쿠라", 23, 163, "AKB48"),
                new Star("나코", 19, 150, "AKB48"),
                new Star("히토미", 19, 158, "AKB48"),
            };

            /* 내부 조인 */
            var InnerJoinData =
                from profile in Izone
                join item in AKB48 on profile.name equals item.name
                select new
                {
                    Name = profile.name,
                    GroupName = profile.groupName,
                    Age = profile.age,
                    Height = profile.height,
                };

            foreach(var item in InnerJoinData)
            {
                Console.WriteLine("이름 : {0}, \t 그룹 : {1}, \t 나이 : {2}, \t 키 : {3}", item.Name, item.GroupName, item.Age, item.Height);
            }

            Console.WriteLine();

            /* 외부 조인 */
            var OuterJoinData =
                from profile in Izone
                join item in AKB48 on profile.groupName equals item.team into ps
                from item in ps.DefaultIfEmpty(new Star() { team = "IZONE" })
                select new
                {
                    Name = profile.name,
                    Age = profile.age,
                    GroupName = item.team,
                    Height = profile.height,
                };

            foreach (var item in OuterJoinData)
            {
                Console.WriteLine("이름 : {0}, \t 그룹 : {1}, \t 나이 : {2}, \t 키 : {3}", item.Name, item.GroupName, item.Age, item.Height);
            }
        }
    }
}

-----------------------------------------------------------------

이름 : 사쿠라,   그룹 : 아이즈원,        나이 : 23,      키 : 163
이름 : 나코,     그룹 : 아이즈원,        나이 : 19,      키 : 150
이름 : 히토미,   그룹 : 아이즈원,        나이 : 19,      키 : 158

이름 : 권은비,   그룹 : IZONE,   나이 : 25,      키 : 160
이름 : 김민주,   그룹 : IZONE,   나이 : 19,      키 : 163
이름 : 조유리,   그룹 : IZONE,   나이 : 19,      키 : 162
이름 : 최예나,   그룹 : IZONE,   나이 : 21,      키 : 162
이름 : 김채원,   그룹 : IZONE,   나이 : 20,      키 : 163
이름 : 강혜원,   그룹 : IZONE,   나이 : 21,      키 : 163
이름 : 장원영,   그룹 : IZONE,   나이 : 16,      키 : 175
이름 : 안유진,   그룹 : IZONE,   나이 : 17,      키 : 169
이름 : 이채연,   그룹 : IZONE,   나이 : 21,      키 : 165
이름 : 사쿠라,   그룹 : IZONE,   나이 : 23,      키 : 163
이름 : 나코,     그룹 : IZONE,   나이 : 19,      키 : 150
이름 : 히토미,   그룹 : IZONE,   나이 : 19,      키 : 158
블로그 이미지

NIA1995

,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace @Sort
{
    class Program
    {
        class StudentData
        {
            private int id;
            private int kor;
            private int math;
            private int eng;
            private int total;

            public int ID
            {
                get { return id; }
            }

            public int Kor
            {
                get { return kor; }
            }

            public int Math
            {
                get { return math; }
            }

            public int Eng
            {
                get { return eng; }
            }

            public int Total
            {
                get { return total; }
            }

            public StudentData(int id, int kor, int math, int eng)
            {
                this.id = id;
                this.kor = kor;
                this.math = math;
                this.eng = eng;

                total = kor + math + eng;
            }
        }

        static void Main(string[] args)
        {
            List<StudentData> dataList = new List<StudentData>();

            bool isLoop = true;

            InitData(dataList, 20);

            do
            {
                Console.WriteLine("메뉴를 골라주세요 !");
                Console.Write("(1)id정렬 (2)성적 순 정렬 (3) 국어 점수 정렬 (4)특정 점수 이상 (5)특정 점수 이하 (0)나가기");
                string inputNum = Console.ReadLine();

                switch (inputNum)
                {
                    case "0":
                        Console.WriteLine("프로그램 종료");
                        isLoop = false;
                        break;

                    case "1":
                        SortDataByID(dataList);
                        break;

                    case "2":
                        SortDataByTotal(dataList);
                        break;

                    case "3":
                        SortDataByKor(dataList);
                        break;

                    case "4":
                        SortData(dataList, true);
                        break;

                    case "5":
                        SortData(dataList, false);
                        break;

                    default:
                        Console.Clear();
                        Console.WriteLine("다시 입력해 주세요!");
                        break;
                }

            } while (isLoop);
        }

            static void InitData(List<StudentData> dataList, int initCount)
        {
            Random rnd = new Random();

            for(int i = 0; i < initCount; ++i)
            {
                dataList.Add(new StudentData(i+1, rnd.Next(0, 101), rnd.Next(0, 101), rnd.Next(0, 101)));
            }
        }

        static void PrintData(List<StudentData> dataList)
        {
            Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", "ID", "KOR", "MATH", "ENG", "TOTAL");
            Console.WriteLine("---------------------------------------");

            for(int i = 0; i < dataList.Count(); ++i)
            {
                Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", dataList[i].ID, dataList[i].Kor, dataList[i].Math, dataList[i].Eng, dataList[i].Total);
            }
        }

        static void SortDataByID(List<StudentData> listData)
        {
            listData.Sort(delegate (StudentData a, StudentData b)
            {
                if (a.ID > b.ID)
                {
                    return 1;
                }
                else if (a.ID < b.ID)
                {
                    return -1;
                }
                else
                {
                    return 0;
                }
            });

            Console.WriteLine("아이디 정렬 !");
            PrintData(listData);
        }

        static void SortDataByTotal(List<StudentData> listData)
        {
            /* var data = 와 같다. */
            IOrderedEnumerable<StudentData> data = 
                from item in listData
                orderby item.Total descending
                select item;

            List<StudentData> sortedData = data.ToList();

            Console.WriteLine("총점 정렬 !");
            PrintData(sortedData);
        }

        static void SortDataByKor(List<StudentData> listData)
        {
            listData.Sort((StudentData a, StudentData b) =>
            {
                return b.Kor - a.Kor;
            });

            Console.WriteLine("국어 기준 정렬 !");
            PrintData(listData);
        }

        static void SortData(List<StudentData> listData, bool isASC)
        {
            Console.Write("기준 점수 입력 : ");
            string targetScore = Console.ReadLine();

            int num = 0;

            try
            {
                num = int.Parse(targetScore);
            }
            catch(FormatException e)
            {
                Console.Clear();
                Console.WriteLine("올바르지 않은 문자 형식입니다. 숫자만 입력 가능 합니다!");
            }
            finally
            {
                if(num < 0)
                {
                    Console.Clear();
                    Console.WriteLine("잘못된 입력 범위 입니다. -1보다 큰 수를 입력하세요 !");
                }
                
                if(num > 300)
                {
                    Console.Clear();
                    Console.WriteLine("잘못된 입력 범위 입니다. 301보다 작은 수를 입력하세요 !");
                }
            }

            if(num > -1 && num < 301)
            {
                if(isASC)
                {
                    var datas =
                        from item in listData
                        where item.Total >= num
                        select item;

                    List<StudentData> sortedData = datas.ToList();

                    PrintData(sortedData);
                }
                else
                {
                    var datas =
                            from item in listData
                            where item.Total <= num
                            select item;

                    List<StudentData> sortedData = datas.ToList();

                    PrintData(sortedData);
                }
            }         
        }
    }
}

'프로그래밍 > 코드 정리' 카테고리의 다른 글

[C#] StreamWriter, StreamReader  (0) 2021.04.02
[C#] BitConverter 테스트  (0) 2021.04.02
[C#] 성적 입력 프로그램  (0) 2021.03.25
[C#] 우승할 달리기 선수 맞추기  (0) 2021.03.21
[C#] 성적 프로그램  (0) 2021.03.20
블로그 이미지

NIA1995

,