简体   繁体   中英

IEnumerable<> instead of List<> goes well when reading objects

Consider my following class Album:

public class Album
{
    public int? Id { get; set; }
    public string Name { get; set; }
    public IEnumerable<Photo> Photos { get; set; }
    public DateTime Registered { get; set; }
}

I have no troubles retrieving data out and populating my album and my photo collection.

However now I also want to 'Add' a Photo item into my Photos collection, 'Add' is not recognized as a valid method on Photos.

'System.Collections.Generic.IEnumerable'does not contain a definition for 'Add' and no extension method 'Add' accepting a first argument of type....

What should I do as a simple thing to get it to work with IEnumerable? I don't want to change my property to

public List<Photo> Photos { get; set;}

Do I really need to implement ICollection on my Album class?

 public class Album : ICollection<Photo> { ... }

If you do not want to change the property type to something that allows addition ( IList<Photo> or ICollection<Photo> ) add a separate method for adding pictures, like this:

public void AddPhoto(Photo p) {
    ...
}

This would let you keep IEnumerable<Photo> as the type of your property, and also allow for validation of what the callers put in. For example, your code would be able to detect if a photo is too big or too small, and throw an exception. This would be a lot harder to do if you exposed IList<Photo> , because you would need to provide your own implementation that overrides Add .

You should also make the setter of your auto property private, or replace the auto property with a getter + a backing field.

Try making Photos a private List then create a standard property exposing it as an IEnumerable. Then add an "AddPhoto" method to your album object.

This way you allow album to control how it adds items to its internal collection.

public class Album
{
    private List<Photo> _photos = new List<Photo>();

    public IEnumerable<Photo> Photos { get { return _photos; } }

    public void AddPhoto(Photo photo)
    {
        _photos.Add(photo);
    }
}

*Edit This is a similar answer to dasblinkenlight, just with a more fleshed out code. I'll leave it here for now as it adds a little bit of clarification.

IEnumerable<T> does not allow sequence to be changed during enumeration. There is no other way but use another interface, such ICollection<T> or IList<T> .

So that the Photos will look like

public IList<Photo> Photos { get; set;}
// or
public ICollection<Photo> Photos { get; set;}

You can of course use actual classes and not interfaces, but usually interfaces give you more freedom.

Try:

myAlbum.Photos = myAlbum.Photos.Concat(newPhoto);

You need to add using System.Linq; on top of your file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM