2012-10-31 20 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

最后一件事:我本来希望私人解决方案的解决方案,但谁阻止我做一个“新的东西()”?那也会覆盖整个对象,而这在接口中是不可能的。你是否同意我的观点?嗯...纠正我。如果我有ISomething,我仍然可以做“ISomething x = new Something();” - 这会覆盖原始对象吗? – timmkrause

2

您应该从接口继承MyBusinessObject并公开该接口。

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

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

然后在集合MyCollection中公开这个接口。

也许对集合做同样的事情,并且不公开add,remove等方法。