2012-10-31 2 views
0

이 중 아무것도 편집 할 필요가 없습니다. 컬렉션의 경우 ReadOnlyCollection을 사용하는 것이 분명해 보입니다. (필자는 컬렉션에서 항상 새로운 ReadOnlyCollection을 만드는 좋은 방법인지는 모르겠지만 비용이 많이 듭니까?)).조회 컬렉션 및 편집 할 항목을 보호하십시오.

public static class Lookups 
{ 
    private static Collection<MyBusinessObject> businessObjects; 
    // [...] 

    public static ReadOnlyCollection<MyBusinessObjects> BusinessObjects 
    { 
     get 
     { 
      return new ReadOnlyCollection<MyBusinessObject>(businessObjects); 
     } 
    } 
    // [...] 
} 

하지만 더 중요한 점은 컬렉션 내부의 항목은 어떻게해야합니까? 나는이 시험이 어떤 생각을 전달하기를 원합니 까?

[TestMethod] 
    public void Items_Should_Not_Be_Editable() 
    { 
     var businessObject = Lookups.BusinessObjects.First(); 

     businessObject.Id = 1337; 

     Assert.AreNotEqual(1337, Lookups.BusinessObjects.First().Id); 
    } 

답변

2

ReadonlyCollection을 사용할 때마다 매번 새 인스턴스를 만들 필요가 없습니다. 대안은 IEnumerable을 읽기 전용이므로 노출하는 것입니다. Readonlycollection은 here처럼 강력한 보호 기능을 제공합니다.

ReadOnlyCollection 제네릭 클래스의 인스턴스는 항상 읽기 전용입니다. 읽기 전용 컬렉션은 단순히 컬렉션을 수정하지 못하게하는 래퍼 인 이있는 컬렉션입니다. 따라서 기본 컬렉션에 변경 내용이있는 경우 읽기 전용 컬렉션에 이러한 변경 내용이 반영됩니다. 이 클래스의 수정 가능한 버전에 대해서는 Collection을 참조하십시오. 귀하의 경우에는

[Test] 
public void TestNameTest() 
{ 
    var names = new List<string>() {"Johan", "Tkrause"}; 
    var readOnlyCollection = new ReadOnlyCollection<string>(names); 
    names.Add("Lars"); 
    Assert.AreEqual(3,readOnlyCollection.Count); 
} 

: 그들은 개인 세터가 있거나 라스에 의해 제안 읽기 전용 인터페이스를 구현할 수있는 비즈니스 오브젝트로

private List<IMyBusinessObjectType> _businessObjects= new List<IMyBusinessObjectType>(); 
private ReadOnlyCollection<IMyBusinessObjectType> _readOnlybusinessObjects; 
public ReadOnlyCollection<IMyBusinessObjectType> BusinessObjects 
{ 
    get 
    { 
     if(_readOnlybusinessObjects==null) 
      _readOnlybusinessObjects=new ReadOnlyCollection<IMyBusinessObjectType>(_businessObjects); 
     return _readOnlybusinessObjects; 
    } 
} 
public interface IMyBusinessObjectType 
{ 
    string Name { get; } 
} 

public class MyBusinessObjectType : IMyBusinessObjectType 
{ 
    public string Name { get; set; } 
} 

.

+0

그러나 이것은 "일반 통계"컬렉션의 두 번째 블록이 필요하다는 것을 의미합니다. 속성은 개인 ReadOnlyCollections를 참조하고 개인 ReadOnlyCollections는 비공개 컬렉션을 참조하며 비공개 컬렉션에 대해 업데이트됩니다. – timmkrause

+0

내 코드가 업데이트되었습니다. ^^ 정적이라고 생각하지 않았습니다. readonlycollection에 관해서는 일반 컬렉션에 대한 래퍼이므로 읽기 전용이므로 올바른 것입니다. –

+0

마지막 사항 : 나는 개인 설정 도구를 선호했을 것이다. 그러나 누가 나를 "새로운 것을 (S)"하는 것을 막을 까? 그것은 완전한 객체를 덮어 쓰고 인터페이스로는 불가능합니다. 당신은 제 의견에 동의하십니까? 나는 ... 정정 해. 내가 무언가를 가지고 있다면, 나는 여전히 "ISomething x = new Something();"을 할 수 있습니다. - 이것이 원래 객체를 덮어 씁니까? – timmkrause

2

인터페이스에서 MyBusinessObject를 상속 받아 노출해야합니다.

internal class MyBusinessObject : IMyBusinessObject { 
    public string Id { get; set; } 
} 

public interface IMyBusinessObject { 
    public string Id { get; } 
} 

그런 다음이 인터페이스를 MyCollection 컬렉션에 표시하십시오.

아마도 컬렉션에 대해 동일한 작업을 수행하고 추가, 제거 등의 메소드를 노출하지 마십시오.

관련 문제