2016-10-21 2 views
6

나는 다음과 같은 유형이 말 :제네릭 형식을 포함하는 배열을 선언하는 방법?

public class Field<T> 
{ 
    public string Name { get; set; } 
    public T Value { get; set; } 
} 

어떻게 이러한 필드의 배열을 포함하는 변수를 선언 할 수 있습니까?

var customFields = new Field[] 
{ 
    new Field<string> { Name = "nickname", Value = "Bob" }, 
    new Field<int> { Name = "age", Value = 42 }, 
    new Field<DateTime> { Name = "customer_since", Value = new DateTime(2000, 12, 1) } 
}; 

하지만 다음과 같은 컴파일 시간 예외가 얻을 : 나는 다음과 같은 시도 제네릭 형식 '필드'를 사용

을 요구 한 형태 인수를

나는 또한 var customFields = new Field<object>[]을 시도했지만 다음 오류가 발생합니다 :

암시 적으로 'Field'유형을 'F' 의 ield '

암시 적 타입 변환 할 수 없습니다'필드 '에'필드 '

암시 적 타입 변환 할 수 없습니다'마티아스는 그렇게 때문에 일을 할 수없는 말했듯이 필드를 '

+4

각 일반 유형은 * 다른 유형 *입니다. 따라서 서로 다른 유형의 인스턴스 배열을 만들려고합니다. 이건 불가능 해. 이것은'string'과'int' 값을 저장할 배열을 만드는 것과 같습니다. 그러나 [공분산] (https://msdn.microsoft.com/en-us/library/dd799517(v=vs.110) .aspx)을 살펴볼 수 있습니다. –

답변

12

'에 '필드 Field<int>Field<string>은 완전히 다른 유형입니다. 당신이 할 수있는 것은 :

은 기본 Field 만들기 일반적인하지 않은 : 다음

public class Field 
{ 
    public string Name { get; set; } 
} 

public class Field<T> : Field 
{ 
    public T Value { get; set; } 
} 

그리고 : 마티아스는 downcasting가의 Value를 얻기 위해 필요합니다 주석으로

var customFields = new Field[] 
{ 
    new Field<string> { Name = "nickname", Value = "Bob" }, 
    new Field<int> { Name = "age", Value = 42 }, 
    new Field<DateTime> { Name = "customer_since", Value = new DateTime(2000, 12, 1) } 
}; 

다른 유형. Value의 각기 다른 유형에 대해 수행 할 특정 논리가있는 경우이를 처리하는 좋은 방법은 Factory 디자인 패턴을 사용하는 것입니다. 공장에서는 각 Field에 대해 정확한 "FieldHandler<T>"을 반환 할 것이고, 이는 작동을 중단하고 필요한 것을 반환합니다.

+5

FYI : 요소의 'Value'속성을 가져 오려면 일반 형식으로 다운 캐스팅해야합니다. –

+0

@MatiasCicero - 그래 ... 그건 사실이야 .. –

+0

아주 좋은 생각이야! 마티아스 (Matias)가 말했듯이, 값을 얻기 위해 캐스팅해야하지만, 구체적인 경우 문자열, int 및 DateTime 만 지원하므로 큰 문제는 아닙니다. 그런데, T를이 세 가지 유형으로 만 제한 할 수 있는지 아는 사람이 있습니까? 'T : string, int, DateTime'의 행을 따라 뭔가가 있습니다. – desautelsj

2

당신이 할 수있는 또 다른 일은 단순히 그 모든 유형 (Object)에 공통 기본 클래스를 사용하는 것입니다.

class Field 
{ 
    public string Name { get; set; } 
    public Object Value { get; set; } 
} 
var customFields = new Field[] 
{ 
    new Field { Name = "nickname ", Value = "Bob" }, 
    new Field { Name = "age", Value = 42 }, 
    new Field { Name = "customer_since", Value = new DateTime(2000, 12, 1) } 
}; 

그러나,이 customFields의 소비자에게 어떤 종류의 처리를 오프로드 될 수 있지만, 특정 필드 이름과 관련된 값 유형이 알려진 경우 잘해야한다.

+0

나는 첫 번째 접근 방식에 동의하고 그 이유는 그것이 내 upvote하지만 하단에 - 그 경우에는 .. 제네릭을 사용하지 왜? ... :) –

+0

맞아! 화이트리스트 형식의 경우를 추가하기로했지만 제네릭을 사용하더라도': T : [types allowed]'을 사용하여 제한 할 수 있습니다. 당신의 upvote 주셔서 감사합니다 :) –

관련 문제