[C#] Interface 예제

2016.07.09 18:24





우선 Car라는 클래스를 만들고 그 클래스를 사용하는 Run이라는 함수를 만들어 본다.


private void Form1_Load(object sender, EventArgs e)
{
Car a = new Car();
Run(a);
Close();
}
public void Run(Car car)
{
MessageBox.Show("run!");
}
public class Car
{
}


이번에는 Bike라는 클래스를 만들고 그 클래스를 사용하는 Run이라는 함수를 만들어 본다.
Run을 표시하기 위해 Car를 위한 것과 Bike를 위한 것이 두 개가 필요하다.

private void Form1_Load(object sender, EventArgs e)
{
Car a = new Car();
Bike b = new Bike();
carRun(a);
bikeRun(b);
Close();
}
public void carRun(Car car)
{
MessageBox.Show("run!");
}
public void bikeRun(Bike bike)
{
MessageBox.Show("run!");
}
public class Car
{
}
public class Bike
{
}


이런 것을 쉽게 사용하기 위해서는 interface를 사용하면 쉽게 아래와 같이 해결할 수 있다.
Vehicle이라는 interface를 만들어 Car나 Bike는 Vehicle이라는 interface를 가지고 있다는 것을 정의한다.
private void Form1_Load(object sender, EventArgs e)
{
Car a = new Car();
Bike b = new Bike();
Run(a);
Run(b);
Close();
}
public interface Vehicle
{
}
public void Run(Vehicle v)
{
MessageBox.Show("run!");
}
public class Car : Vehicle
{
}
public class Bike : Vehicle
{
}

Interface는 아래와 같이 Method를 정의할 수 있다.
Interface는 실제 함수를 쓸 수는 없고 함수의 형태만 정의할 수 있다.
Interface를 상속하는 클래스에서 Interface에 정의된 함수를 반드시 구현해야만 된다.

private void Form1_Load(object sender, EventArgs e)
{
Vehicle a = new Car();
Vehicle b = new Bike();
Run(a);
Run(b);
Close();
}
public void Run(Vehicle vehicle)
{
MessageBox.Show(vehicle.getName() + " run!");
}
public interface Vehicle
{
String getName();
}
public class Car : Vehicle
{
public String getName()
{
return "Car";
}
}
public class Bike : Vehicle
{
public String getName()
{
return "Bike";
}
}














Posted by 떡잎


PostgreSQL에서는 컬럼을 배열형으로 만들 수 있다.


배열형 컬럼 만들기


CREATE TABLE member(

    id     serial  PRIMARY KEY,

    name     varchar(20),     

    age      integer,         

    hobby    varchar(100)[]  -- 배열형 컬럼

);


테이블을 만들 때 위와같이 컬럼 타입뒤에 []를 붙이면 배열형 컬럼이 된다.


배열형 컬럼에 데이터 추가하기


INSERT INTO member (name, age, hobby

  VALUES('kim', 10, '{book, music}');


배열형 데이터를 {} 안에 ","로 구분해서 입력한다.


INSERT INTO member (name, age, hobby) 

  VALUES('lee', 12, '{game}');


데이터를 하나만 넣을 때는 위와 같이 쓴다.


INSERT INTO member (name, age, hobby) 

  VALUES('park', 11, ARRAY['movie','sing','craft']);


ARRAY를 사용하여 추가할 수도 있다.

ARRAY를 사용하면 각 항목별에 따옴표를 달아야 된다.



INSERT INTO member (name, age, hobby) 

  VALUES('hong', 9, '{baseball,soccer,swim, tennis,book}');


INSERT INTO member (name, age, hobby) 

  VALUES('ha', 15, '{golf, cartoon, drink, sing, dance}');


테스트용 데이터



배열형 컬럼을 가진 데이터 읽어오기


SELECT * FROM member;

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

1;"kim";10;"{book,music}"

2;"lee";12;"{game}"

3;"park";11;"{movie,sing,craft}"

4;"hong";9;"{baseball,soccer,swim,tennis,book}"

5;"ha";15;"{golf,cartoon,drink,sing,dance}"


배열형 컬럼은 대괄호에 각 항목들이 쉼표로 구분되어진다.


SELECT name, hobby[1] FROM member;

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

"kim";"book"

"lee";"game"

"park";"movie"

"hong";"baseball"

"ha";"golf"


배열형 컬럼의 첫번째 데이터만을 읽어 오기


SELECT name, hobby[2], hobby[3] FROM member;

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

"kim";"music";""

"lee";"";""

"park";"sing";"craft"

"hong";"soccer";"swim"

"ha";"cartoon";"drink"


배열형 컬럼의 두번째와 세번째 데이터를 읽어 오기

해당 순번에 데이터가 없으면 데이터가 안나온다.


SELECT name, hobby[2:5] FROM member;

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

"kim";"{music}"

"lee";"{}"

"park";"{sing,craft}"

"hong";"{soccer,swim,tennis,book}"

"ha";"{cartoon,drink,sing,dance}"


항목의 2번째에서 5번째 값을 읽어올 때는 위와 같이 쓴다.



SELECT * FROM member

  WHERE hobby[1] = 'game';

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

2;"lee";12;"{game}"


첫번째 항목인 'game'인 것을 찾을 때


SELECT * FROM member

  WHERE 'book' = ANY(hobby);

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

1;"kim";10;"{book,music}"

4;"hong";9;"{baseball,soccer,swim,tennis,book}"


항목 중에 book이 있는 것을 찾을 때


SELECT id, (SELECT COUNT(arrayColumn) FROM UNNEST(hobby) arrayColumn) as array_count 

FROM member;


배열 컬럼에 항목이 몇개 들어있는지를 알고 싶을 때


● 배열형 컬럼을 가진 데이터 갱신하기


UPDATE member SET hobby = '{swim, movie, racing}'

  WHERE id = 1;


배열 컬럼의 전체 항목을 바꿀 때


UPDATE member SET hobby[3] = 'sing'

  WHERE id = 1;


배열 컬럼의 3번 째 항목을 바꿀 때


UPDATE member SET hobby[5] = 'fishing'

  WHERE id = 1;


해당 필드의 항목이 3개있는 경우에 5번째 데이터를 변경하면 4번째는 NULL값이 들어간다.


UPDATE member SET hobby[2:4] = '{golf, sing, movie}'

  WHERE id = 2;


구간을 지정해서 항목을 변경할 수 있다.


UPDATE member SET hobby = array_append(hobby, 'game')

  WHERE id = 3;


배열 컬럼에 새로운 항목을 추가하고 싶을 때



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


포스트그레스큐엘은 너무 자료가 없다.

특히 우리나라에는 익숙해지는데 시간이 좀 걸릴 것 같다. -.-

Posted by 떡잎

PostgreSQL의 트리거와 펑션 예제를 만들어 봤다.

자료를 찾는데 너무 힘들어서 나중에 잊기전에 정리해봤다.




● 우선 테스트용 테이블 작성 


CREATE TABLE datalog(

    logtime timestamp PRIMARY KEY,

    data varchar,

    content varchar

);


* 테이블 지우기

DROP TABLE datalog;


● 펑션(Function) 함수 예제

    이 함수가 실행되면 지정 테이블의 레코드가 10개를 넘으면 가장 오래된 것부터 지운다.


CREATE FUNCTION data_fun() RETURNS trigger AS $data_fun$

    DECLARE

rowcount integer;

        delcount integer;

        maxcount integer;

    BEGIN

        maxcount := 10;

        SELECT count(*) logtime into rowcount  FROM datalog;

        delcount := rowcount - maxcount + 1;


        IF delcount > 0 THEN

   DELETE FROM datalog WHERE logtime IN (SELECT logtime FROM datalog ORDER BY logtime LIMIT delcount);

        END IF;


RETURN NEW;

    END;

$data_fun$ LANGUAGE plpgsql;


* 펑션 지우기

DROP FUNCTION data_fun();


● 트리거(Trigger) 함수 예제

    지정 Table에서 추가나 변경이 이루어질 때 지정 펑션이 실행된다.


CREATE TRIGGER data_trg BEFORE INSERT OR UPDATE ON datalog

    FOR EACH ROW EXECUTE PROCEDURE data_fun();


* 트리거 지우기

DROP TRIGGER data_trg ON datalog;



● 테스트용 데이터


insert into datalog(logtime, data) values('2015-01-01 12:12:01', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:12:02', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:12:03', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:12:04', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:12:05', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:12:06', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:12:07', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:12:08', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:12:09', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:13:01', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:13:02', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:13:03', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:13:04', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:13:05', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:13:06', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:13:07', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:13:08', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:13:09', 'aa');


위의 데이터를 입력하면 로그는 10개 행만 테이블에 저장된다.
데이터를 추가하기 전에 트리거의 연결된 펑션이 실행되어
테이블의 행이 10개를 넘어가면 가장 옛날 데이터를 삭제한다.




Posted by 떡잎

Xcode에서 프로젝트 만들어서 간단한 프로그램을 만드는 것은 패스

구구단 2단 출력하는 소스스


ViewController.m 화일에 소스를 입력한다.

#import "ViewController.h"


@interface ViewController ()


@end


@implementation ViewController


- (void)viewDidLoad

{

    [super viewDidLoad];

    // 사용할 라벨 배열 정의

    UILabel *lb[9];

    

    for(int i=1; i < 10; i++){

        // 라벨 초기화

        lb[i] = [[UILabel alloc] init];

        // 라벨 위치 설정(라벨 x좌표, 라벨 y좌표, 라벨 , 라벨 높이)

        lb[i].frame = CGRectMake(10, i * 20, 400, 20);

        // 라벨 문자열 설정

        lb[i].text = [NSString stringWithFormat:

                      @" 2 * %d = %d", i, 2 * i];

        [self.view addSubview:lb[i]];

        

        self.view.backgroundColor = [UIColor whiteColor];

    }

}


- (void)viewDidUnload

{

    [super viewDidUnload];

    // Release any retained subviews of the main view.

}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

{

    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);

}


@end


Posted by 떡잎

DLL 소스

먼저 간단한 DLL을 만든다.

DLL을 만들 때에는 C#에서는 클래스 라이브러리로 만든다.

프로젝트를 하나 만드는데 클래스 라이브러리로 만든다.

네임스페이스는 각자 프로젝트 이름에 따라 달라짐으로 소스를 볼때 주의가 필요하다.

원격 객체일 경우는 아래의 소스와 같이 클래스에 : MarshalByRefObject에 붙여 주어야 된다.

using System;


namespace LunchCompo
{
     // 원격 객체일 경우 아래와 같이 써준다.
    public class Lunch : MarshalByRefObject
    {
        string[] MyMenu = { "짬뽕", "초밥", "순대" };

        public string TodayMenu()
        {
            Random random = new Random();
            int randomNumber = random.Next(0, MyMenu.Length - 1);

            return MyMenu[randomNumber];
        }
    }
}


클라이언트 쪽 소스

그리고 같은 솔루션에서 오른쪽 클릭을 하여 추가 > 새 프로젝트를 선택하여 콘솔 응용 프로그램을 추가한다.

그리고 아래의 소스를 참고해서 소스를 입력한다.


using System;

using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

using LunchCompo;

namespace RemotingDll
{
    class Program
    {
        static void Main(string[] args)
        {
            // 클라언트 채널 만들기
            TcpClientChannel channel = new TcpClientChannel();
            // 채널 등록하기
            ChannelServices.RegisterChannel(channel, false);
            // 원격 객체 설정(원격 객체의 주소)
            RemotingConfiguration.RegisterWellKnownClientType(
                typeof(Lunch),
                "tcp://127.0.0.1:7777/Lunch.bin");

            // 가상 객체 프록시
            Lunch l = new Lunch();

            //리모팅 객체(원격 프럭시)인가
            if (RemotingServices.IsTransparentProxy(l))
                Console.WriteLine("원격객체");
            else
                Console.WriteLine("로컬객체");

            // 마샬 바이 레퍼런스
            // 원격 객체의 메서드 호출
            Console.WriteLine(l.TodayMenu());
            Console.ReadLine();
        }
    }
}



네임스페이스에 주의하면 위 소스를 추가하면 using System.Runtime.Remoting.Channels.Tcp와 using LunchCompo에 빨간 줄이 간다. 그것은 참조 추가에서 추가한다.
RemotingDll의 프로젝트의 참조에서 using System.Runtime.Remoting.Channels.Tcp는 닷넷 탭에서 추가하고 using LunchCompo는 프로젝트 탭에서 추가한다.

● 서버 쪽 소스

그리고 같은 솔루션에서 오른쪽 클릭을 하여 추가 > 새 프로젝트를 선택하여 콘솔 응용 프로그램을 추가한다.

그리고 아래의 소스를 참고해서 소스를 입력한다.


using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

using LunchCompo;

namespace RemotingServer
{
    class Program
    {
        static void Main(string[] args)
        {
            // 채널 만들기 (7777 포트 번호)
            TcpServerChannel channel = new TcpServerChannel(7777);
            // 채널 등록하기
            ChannelServices.RegisterChannel(channel, false);
            // 원격 객체 준비 작업
            RemotingConfiguration.RegisterWellKnownServiceType(
                typeof(Lunch),
                "Lunch.bin",
                WellKnownObjectMode.SingleCall);
            // SingleCall 한번 만 실행되고 실행이 끝나면 종료된다.

            Console.WriteLine("종료:Ctrl+z");
            while (true)
            {
                if (Console.ReadLine() == null)
                    break;
            }
        }
    }
}



서버 쪽 프로젝트에서도 using System.Runtime.Remoting.Channels.Tcp와 using LunchCompo를 사용하기 위해서는 참조에서 반드시 추가를 해주어야 된다.

서버를 먼저 실행한 뒤 클라이언트 프로그램을 실행하면 서버에서 리모팅으로 클래스를 불러와 클래스의 메서드를 실행한다.

요즘은 리모팅은 MS에서는 추천하지는 않고 WCF를 추천한다고 한다.
사람들의 MS의 추천을 따르고 있는지는 잘 모르지만 여하튼 MS가 지원을 잘 안하려는 것을 열심히 공부하는 것은 좀 생각은 해봐야 될 것같다.

개인적으로 서버의 클래스를 클라이언트에서 가져다가 쓸 수 있는 것은 굉장하다는 생각이 들었다.

Posted by 떡잎

C#에서 DLL만들고 사용하기

개발환경은 Visual C# 2010 Express에서의 예제이다.
이 내용은 Visual Studio 2010에서 해도 문제가 없다.

메뉴 표시는 대신 한글이여서 조금은 이해하기 편할 것 같다.


먼저 DLL을 사용할 프로젝트를 만든다.
먼저 File > New Project를 선택한다.

Console Application을 선택하고 적당한 이름을 입력한 후 OK를 누른다.
여기서 입력한 이름으로 프로젝트가 만들어지고 이 이름의 네임스페이스가 생긴다.

그러면 아래와 같이 자동으로 소스가 조금 만들어진다.


사용할 DLL 프로젝트 만들기

솔루션에서 왼쪽 클릭을 하고 Add > New Project를 선택한다.



Class Library를 선택하고 DLL의 이름을 적고 OK를 누른다.


DLL에 대한 내용을 적어둔다.



using System;

namespace MyCompo
{
    public class Calcurate
    {
        public int Add(int a, int b)
        {
            return (a + b);
        }
    }
}


DLL을 Build한다.


작성된 DLL을 참조하기 위해서는 DLL을 사용하려는 프로젝트의 References(참조)에서 오른쪽 클릭을 하여 Add Reference를 선택한다.


그리고 Projects 탭을 선택하면 지금 작성한 DLL의 프로젝트를 선택하고 OK를 누른다.

정상적으로 Dll이 참조되면 References 밑에 추가한 DLL의 이름이 표시된다.

그리고 아래와 같이 코드를 작성한다.


using System;
// DLL Namespace 추가
using MyCompo;

namespace UseDll
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 10;
            int b = 20;
            int c = 0;

            // DLL에 정의된 클래스로 객체 정의하기
            Calcurate cal = new Calcurate();

            // DLL의 메서드 사용하기
            c = cal.Add(a,b);

            Console.WriteLine("{0} + {1} = {2}", a, b, c);
            Console.ReadLine(); 
        }
    }
}

그리고 실행하면 아래와 같은 결과가 표시된다.




Posted by 떡잎
 Delphi에서 Firebird를 사용하기위한 무료 Component인 ZoesLib 설치하기
(ZoesLib는 Firebird 뿐 아니라 여러 다른 database도 지원한다.)

ZoesLib가 지원하는 databse들

• MySQL 3.20 - 5.0
• PostgreSQL 6.5 - 8.1
• Firebird 1.0 - 2.0
• Interbase 5.0 - 7.5
• Microsoft SQL Server 7, 2000
• Sybase ASE 12.0, 12.5
• Oracle 9i
• SQLite 2.8, 3.5

설치 SW version
  • Delphi 2006
  • Firebird 2.5
  • ZeosLib 6.6.6
1. ZeosLib 설치 순서

1) ZeosLib 사이트에서 ZeosLib를 Download한다.
http://sourceforge.net/projects/zeoslib/

2) Download한 파일의 압축을 푼다.
압축을 풀면 아래의 네개의 Folder가 만들어진다.
    - doc
    - examples
    - packages
    - src
3) Delphi가 설치된 곳의 Lib folder에 ZeosLib folder를 만들고 위의 네 folder를 복사해서 붙인다.
C:\Program Files\Borland\BDS\4.0\lib\ZeosLib

4) Packages folder의 delphi11 folder에서 groupproj를 열고 싶었지만 Delphi 2006에서는 열 수 없어서 아래의 dpk file들을 delphi에서 하나씩 열었다.
• ZCore.dpk
• ZParseSql.dpk
• ZPlain.dpk
• ZDbc.dpk
• ZComponent.dpk
그리고 위의 순서대로 아래의 그림과 같이 각 project에서 오른쪽 click을 하여 compile을 한다.


5) 위 compile을 마친 후 ZComponentDesign.dpk를 열어서 Compile한 후 Install을 한다.
그러면 아래와 같이 Form에 붙여서 사용할 수 있는 Component가 표시된다.


6) Delphi menu의 Tools > Options...를 선택하면 아래의 창이 표시된다.

Environment Options > Delphi Options > Library - Win32에서 Library를 선택하면
오른쪽에 Directories가 표시된다.

거기서 Library path, Borwsing Path, Debug DCU path에 아래의 path를 입력한다.

    ;C:\Program Files\Borland\BDS\4.0\lib\ZeosLib\src\component
    ;C:\Program Files\Borland\BDS\4.0\lib\ZeosLib\src\core
    ;C:\Program Files\Borland\BDS\4.0\lib\ZeosLib\src\dbc
    ;C:\Program Files\Borland\BDS\4.0\lib\ZeosLib\src\parsesql
    ;C:\Program Files\Borland\BDS\4.0\lib\ZeosLib\src\plain

(주의 : ZeosLib를 어느 folder에 복사했는지에 따라 위 path는 변경된다.)



7) Windows folder의 system folder에 사용하고자 하는 database의 client dll을 복사해서 붙여넣어야 된다.

Firebird의 경우 : Firebird가 설치된 folder의 bin folder에 fbclient.dll를 Windows의 system folder에 복사하여 붙여넣는다.
(default path에 설치한 경우 : C:\Program Files\Firebird\Firebird_2_5\bin)

2. ZeosLib 간단 사용법

1) Form에 먼저 Zeos Access에서 TZConnection을 붙여넣는다.


Database : Firebird Database file path를 입력한다.
Password : SYSDBA의 password를 변경하지 않았을 경우 masterkey를 입력한다.
Protocol : firebird-2.1을 선택한다.(2.5도 지원은 되는 것 같음)
User : Firebird의 기본 User 명을 변경하지 않았으면 SYSDBA를 입력한다.
Connected : true로 설정한다.

2) Form에 Zeos Access에서 TZQuery를 붙여넣는다.


Connection : 1)에서 설정한 TZConnection의 name을 선택한다.
SQL : SQL문을 입력한다. (예: select * from table명 )
Active : true로 설정한다.

3) Form에 Data Access에서 TDataSource를 붙여넣는다.


DataSet : 2)에서 설정한 TZQuery의 name을 선택한다.

4) Form에 Data Controls에서 TDBGrid를 붙여넣는다.


DataSource : 4)에서 설정한 TDataSource의 name을 선택한다.



5) F9를 눌러 Run을 하면 아래와 같이 Table에 있는 내용들이 표시된다.


Coding 없이 property 설정만으로 이렇게 Database 내용을 볼 수 있다.

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

오늘 하루 종일 Firebird 설치하고 사용방법 정리하다가 하루가 다가는군
몇 일지나면 바로 잊어버려서 우선 설치 방법과 사용방법을 정리


Delphi 2010인 경우는 아래 link 참조

윈도7 델파이 2010에서 Zeos 빌드하기


Posted by 떡잎
BLOG main image
프로그래밍 공부하면서 써가는 개인 노트 (따라서 여기에 씌여있는 소스의 신빙성을 보장 못함 -.-;;) 이 블로그 보면서 틀린 점이 있으면 꼬옥 알려주세요. by 띠리

공지사항

카테고리

분류 전체보기 (323)
Win32 SDK 초보 (27)
통신관련 (11)
MFC TIP (20)
C/C++ TIP (10)
개발기타 (10)
링크 (2)
견물생심 (24)
이것저것 (8)
용어메모 (3)
데이터베이스 (32)
비주얼 베이직 (10)
하드웨어 (3)
C# (42)
Xcode (3)
델파이 (82)
홈페이지 (5)
MindStorm (0)
낙서 (5)
스크래치 (0)
기타 (6)
아두이노 (1)
라즈베리파이 (2)
안드로이드 (6)
파이썬 (0)
WEB (2)
Total : 964,050
Today : 65 Yesterday : 370