아직 제대로 아는거 같지도 않고.
응용도 못하겠지만.
reflection이라는건 참으로 유용한거 같네요.
이전에 실버라이트쪽에서 reflection으로 페이지 호출하는거 포스팅도 했었는데.
이번엔 간단한 method reflection 예제입니다.

아주 간단한데.
이게 잘 쓰면 코드량을 상당히 줄여줄꺼 같네요...
(이러라고 쓰는게 맞는건 아닌거 같지만. ㅋ)


MethodInfo method = (메소드를 가지고 있는 인스턴스?)GetType().GetMethod("메소드명");
method.Invoke((호출할 인스턴스), (파라미터));

이런식으로 쓰면 됩니다.

만약에 GetMethod에 넣은 메소드명이. 존재하지 않는 메소드라고 하면
method는 null이 되므로
method.Invoke를 호출하기 전에 null 체크를 해주는게 좋겠죠?

그리고
도움말에 나오지만
Invoke의 첫번째 파라미터는 static method의 경우는 무시되고
두번째 파라미터는 Object[] 형식이고
파라미터가 없는 메소드의 경우에는 null입니다.

*추가 주의사항
  전혀 모르고 있다가 MSDN찾아보고 알게된게 있네요..
 GetMethod로 메소드를 찾을때 해당 메소드는 public이여야 합니다... ㅠㅠ 몰라서 한참 헤맸네요. ㅠㅠ
by 피요히코~ 2010. 4. 29. 15:15

Array형식이나 List형식의 데이터는 index를 이용해 해당 데이터에 접근할수 있어요
뭐 예를들자면
List listStr = new List();
listStr.Add("1");
listStr.Add("2");

MessageBox.Show(listStr[1]);

뭐 이런식으로 하면
list의 두번째 데이터인 "2"가 출력되죠.

코딩을 하다보면
내가 원하는 데이터를 따로 담아두기 위해 클래스를 만들기도 합니다.(구조체든지.)

그 클래스에서는 프로퍼티 등을 통해 외부에서 엑세스 할수 있도록 해주죠.

하지만 외부에서 엑세스 하는 변수가 (예를들어) List<T> 형식인 경우

물론 외부에서 그 변수를 그대로 얻어와서
핸들링 할수도 있겠지만.
클래스 자체에서의 작업을 통해
index를 통해 접근 할수도 있습니다.

public 형식 this[int index]
{
     get
    {
        return List[index];
    }
}

뭐 이런식으로 해주면 됩니다.
클래스 외부에서 접근을 해야 하니 당연히 public이겠구요
형식은 뭐. 해당 list의 형식과 맞춰주면 되겠죠.

그리고 이왕이면
Add/Insert/Remove/IndexOf 등의 메서드도 구현해놓는다면
사용할때 더 편리하겠죠?
by 피요히코~ 2010. 4. 26. 14:37
윈폼에서 유저컨트롤을 만들면. 도구상자에 추가가 되서. 일반 컨트롤처럼 사용할수가 있죠

유저컨트롤을 만들어서 쓰다 보면
속성을 추가하고 싶은 마음이 슬금슬금 생길수도 있는데

일반 속성 만드는거 처럼 만드니
디자인창에서 컨트롤속성을 봐도 추가가 되어있진 않더라구요

방법은?!!

[Category("속성명"),Description("설명")]


이렇게 하기만 해주면 됩니다. ㅋ

참 쉽죠잉!!!

[Category("IsNumber"), Description("숫자인지 여부")]
public bool IsNumber
{
       get;
       set;
}

이렇게 해주면 디자인창에서도 속성편집을 할수 있습니다.
by 피요히코~ 2010. 1. 13. 11:58
일단 만들어질 COM+을 사용할 기본 웹프로젝트를 하나 만들고
거기에 COM+ 을 구현하기 위한 프로젝트도 만들어줍니다~

대충 이런 모양이 됩니다.
웹프로젝트명은 Hello_Complus고. COM+ 프로젝트는 HelloComplus로 만들었어요
웹프로젝트에는 COM+에 대한 참조를 추가해주고
COM+ 프로젝트에는 System.EnterpriseServices를 추가해줍니다.

이제 COM+ 프로젝트에 Hello.cs라는 클래스를 추가해주고 코드를 작성해줍니다.



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.EnterpriseServices;

namespace HelloComplus
{
    //public으로 해줘야 겠죠?!
    public class Hello : ServicedComponent
    {
        public Hello()
        {
            //생성자
        }

        public string SayHello()
        {
            return "Hello!!!";
        }
    }
}

이 상태에서 웹프로젝트에서 SayHello 메소드를 호출할수는 없어요
COM+을 사용하기 위해선 몇가지가 더 필요합니다.

COM+ 는 반드시 강력한 이름을 가져야 합니다.

명령프롬프트에서 명령어로 어셈블리에 강력한 이름으로 서명을 할 수 있습니다.
VS 도구에있는 명령 프롬프트를 실행해서
 sn -k HelloComplus.snk
해서 새로운 키쌍을 생성 한 후에
COM+프로젝트의 Properties 아래에 있는 AssemblyInfo.cs에서 해상 키 파일을 등록해주면 됩니다.

AssemblyInfo.cs에서 고쳐주어야 할 께.
// ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에 
// 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면 
// 해당 형식에 대해 ComVisible 특성을 true로 설정하십시오.
[assembly: ComVisible(true)]

ComVisible부분을 true로 해주는것과(기본은 false에요)
[assembly: AssemblyKeyFile("HelloComponent.snk")]

이렇게 만들어진 키 파일을 등록해 주면 됩니다.

(COM+이 강력한 이름을 가져야 하는 이유는 COM+가 시스템 레지스트리에 등록되어야 하기 때문이라고 합니다...)

그 후에는 COM+을 등록시켜주면 되는데요
좀전에 키파일을 만들때 처럼
명령 프롬프트에서

COM+프로젝트의 obj/Debug/ 에 들어가면 dll이 만들어져있잖아요. (아. 물론. 프로젝트를 컴파일해 줘야 합니다.)

regsvcs HelloComplus.dll 이라고 해주면 됩니다.

이 명령을 실행하기 전에 먼저. 해당 파일이 있는 경로까지 들어가야 해요.

그러면

이렇게 등록이 됩니다.
그럼 이놈은
레지스트리에도 등록이 되어있고
구성요소 서비스에도 등록이 됩니다.


찾아보면. 이렇게 등록되어 있는걸 볼수 있습니다.

이제 이 COM+이 사용이 되는지 간단하게 테스트를 해볼꼐요

웹프로젝트의 Default.aspx의 비하인드코드의 Load부분에 간단히 코드를 작성합니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using HelloComplus;

namespace Hello_Complus
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Hello hello = new Hello();
            Response.Write(hello.SayHello());
        }
    }
}

그리고 실행을 하면


이렇게 나오네요

성공!!

근데. 한가지 문제아닌 문제가 있어요

COM+ 프로젝트를 빌드할때
오류는 없지만 경고가 뜹니다.


이런 오류인데요
아까 AssemblyInfo.cs에 키파일을 등록한 부분에서 나는 문제입니다.

사실 이렇게 나와도잘 되는데
(이게 .net framework와 vs 이전버전에서 사용했던 방법인가봐요)

그래도 이런 경고가 안나오게 하려면

    강력한 이름을 만들때 명령 프롬프트에서 sn으로 등록하지 말고
    COM+ 프로젝트의 속성에서 직접 만들어 줍니다.


이렇게만 하면
sn으로 키파일 만들고.
등록하고. 하는게 필요 없더라구요
(당연히 경고도 안나오죠..)

여기까지가 (아주)간단한 COM+ 만들기 였습니다.
by 피요히코~ 2010. 1. 6. 14:01
C:\Windows\Microsoft.NET\Framework\v2.0.50727\regsvcs.exe (등록할 dll 이 있는 Full Path)


ex) C:\Windows\Microsoft.NET\Framework\v2.0.50727\regsvcs.exe D:\PROJECT\Vision_Off\02_DAC\VLD.DAC\bin\Debug\VLD.DAC.dll
by 피요히코~ 2010. 1. 5. 16:50
원하지 않는 메소드의 상속..

ex)
어떤 값을 저장하고 보여주는
ArrayList라는 클래스를 상속받아서
MyArrayList라는 클래스를 만들었음


 
public class MyLIst : ArrayList
{
     public void add(object obj)
     {
          base.Add(ojb);
     }
     public object pop(int index)
     {
          return base[index];
     }
}

근데 이걸 또 어떤 사람이 가져다 사용

근데 이걸 사용하다 보니
값을 없앨일이 생겨서
. 찍고 인텔리센스를 보니
clear() 메소드가 있음

그래서 사용하지만.
이건 사용자가 원하는데로 동작을 하지 않아요.

MyList에 있는 메소드가 아니라. ArrayList에서 상속받아진 메소드이기 때문에!
by 피요히코~ 2009. 10. 15. 10:13

abstratct class와 interface의 차이점을 말하기 전에 abstract class 와 interface는 무었인가..?
abstract clss는 보통 abstract 매소드를 가진 class 이며 객체를 생성 할 수 없다.
abstract method 는 또 뭐란 말이냐??

abstract method는
모두 virtual 매소드 이며 하위 클래스에서 상속을 받는다면 반드시 구현해 주어야 하는 매소드 이다.

virtual 매소드는??
기반형의 매소드가 아닌 현재형의 매소드가 호출될 수 있도록 하는 키워드..

그렇다면 이 둘의 차이는 무었일까.
abstract class는 생성자를 가질수 있다. 그러나 interface는 그럴수 없다.
abstract class는 abstract가 아닌 매소드를 가질수 있다. 그러나 interface는 그럴수 없다.
abstract class는 맴버 변수를 가질 수 있다 .그러나 interface는 그럴수 없다.
abstract class는 매소드의 접근자 모두를 가질수 있다. public, private, internal.. ect
그러나 iterface 는 public만 가질수 있다.
abstract class는 클래스 이므로 하나만 상속이 가능하나. interface는 다중 상속이 가능하다.

그럼 언제 이 둘을 사용하여야 하는가??
당연히.. is a 관게일땐 abstract class ,
다른 연관이 없는 class에서 기능을 사용하고 싶을 경우는 interface는 사용하는 것이 좋겠다.

[출처] C# 에서 abstract class와 interface의 차이점?|작성자 갑환
by 피요히코~ 2009. 10. 15. 09:54

작업을 하다보면 DataTable을 쪼물딱 거릴일이 생길수 있다
DataTable의 내용을 다른 DataTable에 넣어야 할일도 생길수 있는데
DataTable.Rows.Add로 그냥 추가해버리면
이미 사용중이라고 안된다고 나온다.
(그래서 지금까진 안썼다는. ㅠㅠ)

아주 간단한 방법이 있었는데.(.NET Framework에서 제공해주는.. ㅠㅠ)

DataTable dt1 = new DataTable();
DataTable dt2 = new DataTable();
//dt1에는 데이터가 채워져있다고 하고
//아주 간단하게
dt2.ImportRow(dt.Rows[index]); //이러면 끝.... ㅠㅠ
//이렇게 넣어주면 dt2에는 dt1의 첫번째 row의 내용들이 들어간다. 
//하지만. 
//단순히 그냥 선언된 dt2는 그냥 텅 비어있는 DataTable이므로
//위의 작업전에 선행 작업이 필요하다.
dt2 = dt1.Clone();
//이렇게 해주면 dt1의 스키마, 관계, 제약조건등 dt1의 구조를 복제해서 dt2에 넣어준다

//dt2의 내용을 지우려면
dt2.Clear();
//해주면 또 끝. 
//쉽다. ㅠㅠ
by 피요히코~ 2009. 10. 7. 14:00
TextBox를 사용하다 보면
그 안에. 특정한 형식만 입력하게 해야할때가 생길수도 있어요.

저같은 경우는
TextBox에 금액형식으로만 데이터가 들어가게 해야 해서
만들었습니다.

//키가 눌러졌을때
private void textbox_KeyPress(object sender, KeyPressEventArgs e)
{
       if (!(char.IsDigit(e.KeyChar) || e.KeyChar == Convert.ToChar(Keys.Back)))
       {
              e.Handled = true;
       }
}

//키가 (눌렸다가) 올라왔을때
private void textbox_KeyUp(object sender, KeyEventArgs e)
{
       TextBox thisText = sender as TextBox;
       text2Money(thisText);
}

//텍스트를 금액 형식으로
private void text2Money(TextBox tbx)
{
       tbx.Text = ConvertEx.DoubleToString(tbx.Text);
       if (tbx.SelectionStart == 0)
       tbx.SelectionStart = tbx.Text.Length;
}

두개의 이벤트와 한개의 메소드 인데요
더 간단하게 될수도 있겠지만
이게 제 한계. --ㅋㅋ

단점은
TextBox에 데이터가 있는 상태에서
커서를 맨 앞으로 가져올수가 없다는것과
데이터를 Double형으로 바꿔서. 크기에 제한이 있다는것

(저기 있는
ConVertEx.DoubleToString(string)은 따로 존재하는 메소드인데요
그냥 Double형으로 Parse한다던지 하면
데이터가 맞지 않을경우 Exception이 날수 있어서 따로 만들어둔거에요
(,도 붙여주구요)
별거 없음. ) 그래도 보나스~~
public static string DoubleToString(string szData)
{
       string szReturn = string.Empty;
       if (szData != "")
       {
              string szValue = szData.Replace(",", "");
              Double data = Double.Parse(szValue);
              szReturn = string.Format("{0:###,###,###,###,###,###}", data);
       }
       return szReturn;
}
by 피요히코~ 2009. 8. 20. 11:36
좀전에 포스팅한 글에 이어서. 두번째 입니다.

당연한 이야기 겠지만.
참조한 DLL로부터 클래스를 상속받을수도 있고, 상속후 메서드를 재정의 할수도 있슶니다.
한번 해보죠.

Client의 소스를 다음과 같이 수정해 볼께요.

namespace Client
{
    class IntCalculator2 : IntCalculator
    {
        public static void PrintMessage()
        {
            Console.WriteLine("요게 되는군요~ :)");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("5+5 = {0}", IntCalculator2.Add(5, 5));
            Console.WriteLine("5-5 = {0}", IntCalculator2.Sub(5, 5));
            IntCalculator2.PrintMessage();
        }
    }
}

IntCalculator를 상속받아서 메서드를 하나 추가를 헀어요.
Add와 Sub 메서드는 IntCalculator2에서도 잘 동작을 하는걸 확인할수 있을겁니다.

닷넷은 언어독립적 특성을 가지고 있어서 C#으로 만든 어셈블리를 VB에서도 사용할수 있습니다.
(하지만 제가 VB를 할줄 모르는군요. ㅎㅎ;;;)
by 피요히코~ 2009. 4. 29. 23:56
| 1 2 3 4 |