레이블이 프랙티컬 C#인 게시물을 표시합니다. 모든 게시물 표시
레이블이 프랙티컬 C#인 게시물을 표시합니다. 모든 게시물 표시

2019년 11월 21일 목요일

C# Dictionary의 value 값으로 key 찾기

1
var _key = Dic.FirstOrDefault(x=>x.Value == "Mon").key;
cs
단순히 linq를 이용해서 찾기

2019년 7월 1일 월요일

List next prev idx 구하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
int nextIdx =  (idx +1) % PageDatas.Count;
 
int prevIdx = (idx -1) % PageDatas.Count;
 
 
 
 
 
public void Next_Page()
 
    {
 
        int idx = PageDatas.IndexOf(currentPage);
 
        if (idx == PageDatas.Count-1)
 
            return;
 
 
 
        int nextIdx =  (idx +1) % PageDatas.Count;
 
        currentPage = PageDatas[nextIdx];
 
        Page_Text_Update();
 
    }
 
    public void Prev_Page()
 
    {
 
        int idx = PageDatas.IndexOf(currentPage);
 
        if (idx == 0)
 
            return;
 
        int prevIdx = (idx -1) % PageDatas.Count;
 
        currentPage = PageDatas[prevIdx];
 
        Page_Text_Update();
 
    }
cs

2019년 6월 6일 목요일

광부 예제(상태 패)

using UnityEngine;
using System.Collections;

public class miner : MonoBehaviour
{
    public enum State
    {
        EnterMineAndDigForNuggets,
        EnterBankAndDepositGold
    }

    public State state;

    public void Awake()
    {
        state = State.EnterMineAndDigForNuggets;

        // Start the Finite State Machine
        StartCoroutine(FSM());
    }

    IEnumerator FSM()
    {
        // Execute the current coroutine (state)
        while (true)
        {
            yield return StartCoroutine(state.ToString());
        }
    }

    IEnumerator EnterMineAndDigForNuggets()
    {
        /* This part works as the Enter function
    of the previous post (it's optional) */

        print("Entering the mine...");
        yield return null;

        /* Now we enter in the Execute part of a state
    which will be usually inside a while - yield block */

        bool dig = true;
        int digged = 0;
        while (dig)
        {
            print("Digging... " + (digged++) + " " + Time.time);
            if (digged == 2) dig = false;
            yield return new WaitForSeconds(1);
        }

        /* And finally do something before leaving
    the state (optional too) and starting a new one */

        print("Exiting the mine...");
        state = State.EnterBankAndDepositGold;
    }

    IEnumerator EnterBankAndDepositGold()
    {
        //Enter
        print("Entering the bank...");
        yield return null;

        //Execute
        bool queing = true;
        float t = Time.time;
        while (queing)
        {
            print("waiting...");
            if (Time.time - t > 5) queing = false;
            yield return new WaitForSeconds(1);
        }

        //Exit
        print("Leaving the bank a little bit richer...");
        state = State.EnterMineAndDigForNuggets;
    }
}

2019년 6월 1일 토요일

추상클래스(C#)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
예제
 
 
 
동물들은 울수 있지만 동물 그 자체는 우는 방식을 결정할 수 없다.
 
그래서 animal의 sound메서드는 본체를 가지지 않는 추상 메서드로 정의
 
동물들은 분형히 울기는 우는데 어떻게 우는지는 Animal단계에서는 정의할수 없고
 
아래 단계까지 내려가야함
 
 
 
namespace Abstract
 
{
 
    abstract class Animal
 
    {
 
        public abstract void sound();
 
    }
 
 
 
    class Dog : Animal
 
    {
 
        public override void sound()
 
        {
 
            Debug.Log("멍멍");
 
        }
 
    }
 
    class Cat : Animal
 
    {
 
        public override void sound()
 
        {
 
            Debug.Log("야옹");
 
        }
 
    }
 
 
 
    class temp : MonoBehaviour
 
    {
 
        private void Start()
 
        {
 
            Abstract.Animal A;
 
            A = new Abstract.Dog(); A.sound();
 
            A = new Abstract.Cat(); A.sound();
 
        }
 
    }
 
    
 
}
 
 
 
출처 : 가메출판사, 닷넷 프로그래밍 정복, 김상형 저
cs

2019년 5월 23일 목요일

파일 존재 확인(c#)

 string _Filestr = _path;
        System.IO.FileInfo fi = new System.IO.FileInfo(_Filestr);

        if (fi.Exists)
        {
            //파일 존재
            __testGetData = FlexDataControl.GetStructFromFile(_path);
        }
        else
        {
            //파일 없음
        }

2019년 5월 20일 월요일

텍스트 파일을 처리하는 프레임워크

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
namespace TextFilePorcessor
 
{
 
    public abstract class TextProcessor
 
    {
 
 
 
        public static void Run<T>(string fileName) where T : TextProcessor, new()
 
        {
 
            var self = new T();
 
            self.Process(fileName);
 
        }
 
 
 
        private void Process(string fileName)
 
        {
 
            Initialize(fileName);
 
            using (var sr = new StreamReader(fileName))
 
            {
 
                while (!sr.EndOfStream)
 
                {
 
                    string line = sr.ReadLine();
 
                    Execute(line);
 
                }
 
            }
 
            Terminate();
 
        }
 
 
 
        protected virtual void Initialize(string fname) { }
 
        protected virtual void Execute(string line) { }
 
        protected virtual void Terminate() { }
 
    }
 
}
cs

TextProcessor 클래스는 abstract(추상)를 붙였으므로 TextProcessor 클래스로부터 상속되다는 것을 전제로 한 클래스입니다.

Run이라는 정적 메서드는 형의 인수를 전달받는 제네릭 메서드입니다.
where T: TextProcessor는 형 T가TextProcessor이거나 TextProcesor를 상속한 서브 클래스
그 뒤에 있는 new()는 형 T가 인수를 가지지 않는 생성자로 인스터스를 생성할 수 있다는 것을 나타냅니다. 이  Run 메서드 안에서는 형 인수 T의 인스턴스를 생성하고 Process 메서드를 호출합니다.

Process 메서드에서는 Initialize, Execute, Terminate 라는 세 개의 메서드를 호출합니다.
이 부분이 다형성을 활용한 부분입니다.
소스코드 상에서는 자기 자신(TextProcessor 클래스)에게 있는 메서드를 호출하지만 실제로 동작할 때는 생성된 인스턴스에 있는 메서드가 호출됩니다.
다형성의 본질인 '다른형을 동일시한다' 라는 개념이 여기에 적용된 것입니다.

Initialize, Execute, Terminate라는 세 개의 메서드는 protected virtual로 지정돼 있으므로
서브클래스에서 오버라이드해서 구체적인 처리를 구현합니다. 아무런 작업도 하지 않아도 된다면 오버라이드하지 않아도 됩니다.




TextProcessor을 이용한 응용 프로그램

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



namespace LineCounter
{
    class Program:MonoBehaviour {


        private void Start()
        {
            TextProcessor.Run<LineCounterProcessor>("fff");
        }
    }
}

public class LineCounterProcessor:TextProcessor  {
    private int _count;

    protected override void Initialize(string fname)
    {
        //base.Initialize(fname);

        _count = 0;
    }
    protected override void Execute(string line)
    {
        //base.Execute(line);

        _count++;
    }
    protected override void Terminate()
    {
        //base.Terminate();
        Debug.Log(_count + "줄");
    }


}

이 콘솔 응용 프로그램 프로젝트의 소스에서는 LineCounterProcessor 클래스에 Initialize, Execute, Terminate라는 세 개의 메서드를 정의했는데 이 메서드를 호출하는 코드는 존재하지 않습니다.
이 메서드를 호출하는 것은 클래스 라이브러리 쪽에 있는 TextFileProcessor 클래스입니다.

여기서는 부모 클래스(TextProcessor)에서 코드의 틀(템플릿)을 마련하고 서브 클래스(LineCounterProcessor)에서 부모 클래스에 있는 메서드를 오버라이드해서 서브 클래스 고유의 기능을 구현했습니다. 이런 패턴을 템플릿 메서드 패턴이라고 합니다. 템플릿 메서드 패턴을 이용하면 서브클래스를 정의하기만 하면 되고 전체적인 처리의 흐름을 작성할 필요가 없기 때문에 '닯았지만 조금 다른 코드'가 양산되지 않게 됩니다.

















2019년 5월 17일 금요일

Linq 예제 (2)

public class Category
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public override string ToString()
        {
            return "ID :"+ ID +",분야 이름 :" + Name;
        }
    }

    public class Book {
        public string Title { get; set; }
        public int Price { get; set; }
        public int CategoryId { get; set; }
        public int PublishedYear { get; set; }
        public override string ToString()
        {
            return "발행연도 :"+ PublishedYear+", 분야 :"+CategoryId + ", 가격 :"+Price+",제목 :"+Title;
        }
    }

    public static class Library {
        // Categories 속성을 통해 나온 분야의 목록을 구할 수 있다.
        public static IEnumerable<Category> Categories { get; private set; }

        //Books 속성을 통해 위에 나온 서적 정보를 구할 수 있다.
        public static IEnumerable<Book> Books { get; private set; }

        static Library(){
            //Categories와 Books에 데이터를 설정한다. 자세한 구현 내용은 생략
        }
    }





특정 분야 내에서 가장 비싼 가격을 구하는 코드
 
1
2
3
 var price = Library.Books
            .Where(b => b.CategoryId == 1)
            .Max(b => b.Price);
cs



최소값인 요소를 한 개만 구하기

1
2
3
4
5
   var min = Library.Books
                         .Min(x => x.Title.Length);
   var book = Library.Books
                         .First(x => x.Title.Length == min);
cs


평균값 이상인 요소를 모두 구한다.

1
2
3
4
5
6
7
8
9
10
11
12
        var average = Library.Books
                            .Average(x => x.Price);
        var aboves = Library.Books
                            .Where(b => b.Price > average);
        foreach(var x in aboves)
        {
            Debug.Log("x:" + x);
        }
cs


중복제거

1
2
3
4
5
6
7
8
9
10
11
12
13
처음 Select 메서드로 발행연도만 구하고 distinct 메서드로 중복을 제거하고 마지막에 OrderBy 메서드로 정렬합니다.
        var query = Library.Books
                            .Select(b => b.PublishedYear)
                            .Distinct()
                            .OrderBy(y => y);
        foreach (var n in query)
        {
            Debug.Log("발행연도 :" + n);
        }
cs


여러 개의 키로 나열한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
여러 개의 키로 나열하려면 OrderBy 또는 OrderByDescending 메서드 뒤에 ThenBy 메서드 나 ThenByDescening 메서드를 호출합니다.
        var books = Library.Books
                            .OrderBy(b => b.CategoryId)
                            .ThenByDescending(b => b.PublishedYear);
        foreach(var x in books)
        {
            Debug.Log("xxxx :" + x);
        }
위의 코드에서는 CategoryId, PublishedYear라는 순서로 나열했습니다. PublishedYear는 ThenByDescending 메서드로 정렬했으므로 최신 발행연도부터 표시됩니다.
cs


여러 요소 가운데 어느 하나에 해당하는 객체를 구한다.


1
2
3
        var years = new int[] { 2013, 2016 };
        var books = Library.Books
                            .Where(b => years.Contains(b.PublishedYear));
cs



GroupBy 메서드로 그룹화한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
GroupBy 메서드를 사용하면 지정한 키마다 요소를 그룹화할 수 있습니다.
발행연도를 기준으로 서적을 그룹화하는 예를 살펴보겠습니다.
        //발행연도를 기준으로 그룹화한다.
        var groups = Library.Books
                            .GroupBy(b => b.PublishedYear)
                            .OrderBy(g => g.Key);
       
        // key가 PublishedYear인 Dictionary생성됨
        //IEnumerable<IGrouping<int,Book>>
        foreach (var g in groups)
        {
            Debug.Log("년:" + g.Key);
            foreach (var book in g)
            {
                Debug.Log(" " + book);
            }
        }
cs


각 그룹에서 최댓값을 가진 객체를 구한다.


1
2
3
4
5
6
7
8
9
10
  //각 발행연도 그룹에서 가장 가격이 비싼 서적을 구한다.
        var selected = Library.Books
                                .GroupBy(x => x.PublishedYear)
                                .Select(b => b.OrderByDescending(a => a.Price).First())
                                .OrderBy(o => o.PublishedYear);
        foreach (var book in selected)
        {
            Debug.Log(book.PublishedYear + "년 제목:" + book.Title + "가격 :" + book.Price);
        }
cs



ToLookup으로 발행연도별로 그룹화한다.
1
2
3
4
5
6
7
8
9
10
11
        var lookup = Library.Books
                            .ToLookup(x => x.PublishedYear);
        var books = lookup[2014];//키를 PublishedYear로 가지는
        foreach (var b in books)
        {
            Debug.Log("book :" + b);
        }
cs


join메서드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
        //Books 와 Categories를 분야 ID로 결합한다
        var books = Library.Books
                           .OrderBy(b => b.CategoryId)
                           .ThenBy(b => b.PublishedYear)
                           .Join(Library.Categories,
                                book => book.CategoryId,
                                category => category.ID,
                                (book, category) => new
                                {
                                    Title = book.Title,
                                    Category = category.Name,
                                    PublishedYear = book.PublishedYear,
                                }
                           );
        foreach (var book in books)
        {
            Debug.Log(book.PublishedYear + "년 제목:" + book.Title + "카테고리 :" + book.Category);
        }
        //join 메서드가 받는 네 개의 인수는 다음과 같다.
        //첫 번째 인수: 결합할 두 번째 시퀀스
        //두 번째 인수: 대상 시퀀스의 결합에 사용할 키
        //세 번째 인수: 두 번째 시퀀스의 결합에 사용할 키
        //네 번째 인수: 결합한 결과로 얻어지는 객체를 생성하는 함수
cs


2016년에 발행된 분야의 목록을 구한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
        var names = Library.Books
                            .Where(b => b.PublishedYear == 2016)
                            .Join(Library.Categories,
                                book => book.CategoryId,
                                category => category.ID,
                                (book, category) => category.Name)
                            .Distinct();
        foreach (var name in names)
        {
            Debug.Log(name);
        }
        //일단 where 메서드로 2016년에 발행된 서적만 골라냅니다. 이렇게 골라낸 서적의 목록과 분야의 목록을 join 메서드로 결합합니다.
        //구하는것은 이름 뿐이므로 마지막 인수에는 category의 name속성만 반환하는 람다식을 넘겨줍니다.
        //마지막에는 Distinct로 중복제거
cs


 GroupJoin으로 그룹화해서 결합한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
        var groups = Library.Categories
                            .GroupJoin(Library.Books,
                            c => c.ID,
                            b => b.CategoryId,
                            (c, b) => new
                            {
                                Category = c.Name,
                                Books = b,
                            });
        foreach (var group in groups)
        {
            Debug.Log(group.Category);
            foreach (var book in group.Books)
            {
                Debug.Log("title :" + book.Title + "발행년도 :" + book.PublishedYear);
            }
        }
//join 메서드와 차이점은 결과가 2차원의 표 형식이 되는 것이 아니고 분야 아래에
여러 서적이 늘어서는 계층 형식으로 결합된다 라는점입니다.
cs




git rejected error(feat. cherry-pick)

 문제 아무 생각 없이 pull을 받지않고 로컬에서 작업! 커밋, 푸시 진행을 해버렷다. push에선 remote와 다르니 당연히 pull을 진행해라고 하지만 로컬에서 작업한 내용을 백업하지 않고 진행하기에는 부담스럽다(로컬작업 유실 가능성) 해결하려...