2013-07-30 6 views
0

일반 클래스가 있으며 해당 유형을 매개 변수 유형으로 사용합니다. 내가 예를 들어, 콘솔 응용 프로그램에서 InsertItem()를 호출 할 때일반 인수가있는 메소드 호출

public class UnlimitedGenericArray<T> 
{ 
private void InsertItem(T item) 
{ 
    this.array[0] = item; 
} 
} 

지금, 내가 실행시 인수의 유형을 알 수있는 방법 : 아래처럼 내 클래스의 메소드에 대한 int?

private void InsertItem(object item) 
    { 
     this.array[0] = (T)Convert.ChangeType(item, typeof(T)); 
    } 

을하지만이 아마 좋은 방법이 아닙니다 :

static void Main(string[] args) 
    { 
     UnlimitedGenericArray<int> oArray = new UnlimitedGenericArray<int>(); 
     while(true) 
     { 
     var userInput = Console.Readline(); 
     oArray.InsertItem(userInput); 
     } 
    } 

내가 대신 다음 아래와 같은 방법에 캐스팅 InsertItem(object item)를 작성할 수 있습니다. 또한 클라이언트에서 인수 유형을 알아야 거기에서 구문 분석을 수행하고 메소드를 호출 할 수 있습니다. 나는 제네릭에 익숙하지 않으니 제발 여기 좀 도와주세요.

+3

어디에서 메서드를 호출하려고합니까? 왜 그것을 호출해야합니까? 'InsertItem (5)'는 잘 컴파일됩니다. 'T'는'int'로 해석됩니다. – Amy

+0

this.array의 유형은 무엇입니까? –

+0

@Amy'main()'내부의 콘솔 응용 프로그램에서 메소드를 호출하려고하는데 클래스를 프로젝트에 추가하려고합니다. 이것은 사용자가 배열에 항목을 삽입 할 수있는 유일한 방법이기 때문에 호출해야합니다. 'InsertItem (5)'는 잘 컴파일되지만 사용자 입력'Console.Readline()'을 읽으므로 내 InsertItem이 인수 유형으로 int를 사용하면'문자열을 int로 변환 할 수 없습니다 '라고 말합니다. – lbrahim

답변

10

은 메서드 본문의 형식을 알지 못합니다. 유형을 알고 있다면 처음부터 제네릭을 사용하지 않았을 것입니다.

여기에 제네릭을 사용하지 않을 수도 있습니다. 유형을 기반으로 결정해야하는 경우 이 아닙니다.

+0

"유형을 기반으로 결정해야하는 경우 방법이 일반적이지 않습니다." - 클래식 ... –

+0

예. 메서드 본문에서 형식을 알지 못합니다. 사용자가 모든 유형의 배열을 초기화 할 수있는 유연성을 갖기를 바랍니다. 그래서 여기서 뭘하려고하는지 이해하기를 바랍니다. 그러면 당신은 어떤 변화를 제안합니까? – lbrahim

0

generic 매개 변수를 int로 지정하면 나중에 해당 유형을 가정 할 수 있습니다. 그래서 콘솔 응용 프로그램의 코드가된다 :

static void Main(string[] args) 
{ 
    // Specifying int here ... 
    UnlimitedGenericArray<int> oArray = new UnlimitedGenericArray<int>(); 
    while(true) 
    { 
    string userInput = Console.ReadLine(); 
    int number = int.Parse(userInput); 
    // ... therefore we know that the method below requires an int 
    oArray.InsertItem(number); 
    } 
} 
+0

아니요, 각하. 앞서 언급했듯이 사용자는'UnlimitedGenericArray '또는'UnlimitedGenericArray '또는 그 유형을 초기화 할 수 있습니다. ** 가정을위한 여지는 없습니다 ** 나는 런타임에 타입을 알아야하고 그것에 따라 파싱해야합니다. – lbrahim

0

마음에 오는 유일한 옵션은 다음과 같이 타입/Func을 사전의 형태로 알려진 유형으로 변환하는 클래스에게 방법을 손으로하는 것입니다 :

public class UnlimitedGenericArray<T> 
{ 
    public IList<T> List { get; set; } 

    private IDictionary<Type,Func<object,T>> InserterFuncDict{get;set;} 

    public UnlimitedGenericArray(IDictionary<Type,Func<object,T>> inserterDict) 
    { 
     this.List = new List<T>(); 

     this.InserterFuncDict = inserterDict; 
    } 

    public void AddItem(object item) 
    { 
     var itemType = item.GetType(); 
     if(itemType == typeof(T)) 
     { 
      this.List.Add((T)item); 
     } 
     else if(this.InserterFuncDict.ContainsKey(itemType)) 
     { 
      this.List.Add(this.InserterFuncDict[itemType](item)); 
     } 
     else 
     { 
      var msg = "I don't know how to convert the value: {0} of type {1} into type {2}!"; 
      var formatted = string.Format(msg,item,itemType,typeof(T)); 
      throw new NotSupportedException(formatted); 
     } 
    } 

} 

그리고 사용은 다음과 같이 보일 것이다 : 그런 다음

var arr = new UnlimitedGenericArray<int>(new Dictionary<Type,Func<object,int>>() 
{ 
    { typeof(string), v => int.Parse(v.ToString()) } 
}); 

// ok! int == T 
arr.AddItem(123); 
// ok, a mapping is provided 
arr.AddItem("123"); 
// Error! 
//"I don't know how to convert the value: False of type System.Boolean into type System.Int32!" 
arr.AddItem(false); 

말한다면, 당신은 당신이 선언을 변경할 수 있습니다 부울 지원을 추가하고 싶었 :

var arr = new UnlimitedGenericArray<int>(new Dictionary<Type,Func<object,int>>() 
{ 
    { typeof(string), v => int.Parse(v.ToString()) } 
    { typeof(bool), v => bool.Parse(v.ToString()) } 
}); 

필요에 따라 유형 변환 사전에 계속 추가하십시오.

관련 문제