2017-01-25 4 views
0

문자열 배열 목록이 있는데이 컬렉션을 모두 읽기 전용으로 만들고 싶습니다.IList <IList<T>> to IReadonlyCollection <IReadonlyCollection >

그래서 나는이 코드를 가지고 :

public XmlPatternTree(IList<string> nodeNames, IList<IList<string>> attributeNames, 
     IList<IList<string>> attributeValues) : this() 
    { 
     NodeNames = new ReadOnlyCollection<string>(nodeNames); 
     AttributeNames = new ReadOnlyCollection<ReadOnlyCollection<string>>(); 
     AttributeValues = attributeValues; 
     Depth = NodeNames.Count; 
    } 

내 문제는 내가 아닌 읽기 전용의 비 읽기 전용 컬렉션 ReadonlyCollection의 ReadonlyCollection을 만들 수 있다는 것, AttributeNames 및 AttributeValues ​​할당은 컴파일 오류가 발생한다는 것입니다 사물.

모든 값을 반복하고 목록에 추가하는 것 외에 다른 작업을 수행 할 수 있습니까?

감사

답변

2

그냥 List<string>,이 일을해야 할 IList<string>에서 유형을 변경하는 경우 : 당신이 당신의 방법 서명을 수정할 수없는 경우

attributeNames.Select((x) => x.AsReadOnly()).ToList().AsReadOnly(); 

(당신이이 IList<string>을 유지) 그러면 다음 작업을 수행 할 수 있습니다.

attributeNames.Select((x) => x.ToList().AsReadOnly()).ToList().AsReadOnly(); 
1

t 그는 .net 프레임 워크가 더 크고 4.0 일반 버전 List<>IReadOnlyCollection<> 인터페이스를 구현합니다. 보다 편리하면 IList<ILIst<>>에서 List<List<>>으로 서명을 바꿀 수 있습니다.

AttributeNames = attributeNames; 
AttributeValues = attributeValues; 
1

(바실의 oreshenski의 대답 유사) IReadOnlyList<out T> 유형의 공분산에 그냥 참고. 당신이하려는 경우

는 :

var nn = new List<string>(); 
var an = new List<string[]>(); 
var av = new List<string[]>(); 
// populate 'nn', 'an', and 'av' 

// the following compiles with no wrapper class: 
var tree = new XmlPatternTree(nn, an, av); 
: 클래스의

public XmlPatternTree(IReadOnlyList<string> nodeNames, 
    IReadOnlyList<IReadOnlyList<string>> attributeNames, 
    IReadOnlyList<IReadOnlyList<string>> attributeValues) : this() 
{ 
    NodeNames = nodeNames; 
    AttributeNames = attributeNames; 
    AttributeValues = attributeValues; 
} 

public IReadOnlyList<string> NodeNames { get; private set; } 
public IReadOnlyList<IReadOnlyList<string>> AttributeNames { get; private set; } 
public IReadOnlyList<IReadOnlyList<string>> AttributeValues { get; private set; } 
public int Depth => NodeNames.Count; 

을, 다음에 언급 된 공분산은 같이 다른 클래스 내부 참조 변환, 및되지 않은 포장을 사용할 수 있다는 것을 의미

물론 사람들은 List<string[]>과 같은 실제 유형으로 인터페이스를 다시 캐스팅 할 수 있으며 형식이 실제로 그 배열 목록이라고 생각한다면 리플렉션을 사용하지 않고 컬렉션을 수정할 수 있습니다. 그러나 그것은 매우 악의적 인 것이므로 "좋은"사람 만 수업을 사용하면 문제가 없다고 가정 할 수 있습니다

PS! 앞서 말했듯이 IReadOnlyList<out T>으로 코딩 된 코드는 공변 ("out")이기 때문에 IReadOnlyCollection<out T>으로 처리했을 수도 있습니다. 속성 (예 : var name = tree.AttrbuteNames[idx1][idx2])에 대한 인덱서 액세스 권한이 없습니다. 하지만 HashSet<>과 비슷한 것을 사용하면 IReadOnlyList<>이 아닙니다.