Create product classes and photos and initialize

1

I have a class Produto and within that class I have a class Categoria and a Class Foto .

1 Product may only have 1 category, but may have multiple Photos.

The problem is with the photos.

I did so:

 public class Produto
 {
    public int ProdutoId { get; set; }
    public string Nome { get; set; }
    public int CategoriaId { get; set; }
    public virtual Categoria Categoria { get; set; }
    public virtual ICollection<Foto> Fotos { get; set; }
 }

public class Categoria
{
    public int CategoriaId { get; set; }
    public string Nome { get; set; }
    public virtual ICollection<Produto> Produtos { get; set; }
}

public class Foto
{
    public int FotoId { get; set; }
    public string Foto { get; set; }
    public virtual Produto Produto { get; set; }
}

And I call them like this:

var produtos = new List<Produto>();
var prod = new Produto { Categoria = new Categoria()};

var foto = new Foto
{
    NomeFoto = "Csa.jhpg"
};
prod.Fotos.Add(foto); // <============= ERRO AQUI
foto = new Foto
{
    NomeFoto = "foto2.jpg"
};
prod.Nome = "nome produto";
prod.Categoria.nome = "categoria de teste";

prod.Fotos.Add(foto);
produtos.Add(prod);

Introducing the error:

  

The reference to an object is not defined for an instance of the object.   in line: prod.Fotos.Add(foto); //ERRO AQUI

    
asked by anonymous 15.01.2016 / 13:38

2 answers

3

You need to start the collection before you can use it, so modify the Produto constructor.

public class Produto
{
    public Produto() 
    {
        this.Fotos = new HashSet<Foto>();
    }

    public int ProdutoId { get; set; }
    public string Nome { get; set; }
    public int CategoriaId { get; set; }
    public virtual Categoria Categoria { get; set; }
    public virtual ICollection<Foto> Fotos { get; set; }
}
    
15.01.2016 / 13:45
4

You already know how to solve the problem, I will complement that the ideal is not to initialize in the constructor. This should be avoided whenever possible. It is not always .

In this case I'd recommend it if you're using C # 6 ( more organized and do not miss anything ):

public class Produto {
    public int ProdutoId { get; set; }
    public string Nome { get; set; }
    public int CategoriaId { get; set; }
    public virtual Categoria Categoria { get; set; }
    public virtual ICollection<Foto> Fotos { get; set; } = new List<Foto>;
}

If you are not using C # 6, this is not possible. Previously only instance variables could be initialized. In this case either would have to create a manual property to initialize the variable that holds the state of the property, or do in the same constructor. Depending on the case, one or the other may be better.

Of course initializing after the built object is less ideal still. This recommendation is valid for initialization within the class, when the instance is built automatically. Although there is a case where the initialization of a member can be made after the constructed object, this is rare and should be avoided. Just do it with great justification.

Note that if you are going to initialize members after the object has been built, it is seldom the correct solution. Either use the default initializer in the (preferred) class, or use the initialization syntax during the declaration of the variable that will hold the object (good when the previous one is not possible or desirable), or do in the constructor. If you leave a member uninitialized already in the build, make sure this is something important for the application, otherwise boot it first.

    
15.01.2016 / 14:05