Create product classes and photos and initialize

Asked

Viewed 287 times

1

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

1 Product may have only 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 that:

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);

Presenting the error:

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

  • 1

    What is the doubt?

  • error in code when I do Photo.ADD Insert

  • The tag java should not be withdrawn?

  • I put java because the syntax for this is identical, the answer of bigtown of course would not work (I think), but feel free to remove if you feel better.

2 answers

5


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

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; }
}
  • worked, could I initialize when I do var Prod = new Product { Category = new Category()}; instead of straight into the class? just out of curiosity

  • 1

    yes, it is possible, but for this type of structure, the ideal is to do it in the same builder.

4

Already know how to solve the problem, I will complement that the ideal is not to make the initialization in the constructor. This should be avoided whenever possible, it is not always.

In this case I would recommend it if using C# 6 (more organized and misses nothing):

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. Before only instance variables could be initialized. In this case either you would have to create a manual property to initialize the variable that stores the state of the property, or do it in the constructor itself. Depending on the case can be better one or the other.

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

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

  • I’m using C#6, I don’t know if I should change to this pattern, I need to read the link and see if I understand 100%. but I believe that changing won’t hurt.. rs

  • I would say it is almost certain that it can use. If it should be a little more complicated to say. I am not seeing a situation that the builder would be useful there. The class is very simple. And I doubt if it becomes complicated enough to require one. The constructor is for cases where the initialization must be done with very complex criteria, conditionally, or needs to be in specific order. If you already had a builder for another reason. This could be different.

  • When you say "the ideal nay is to initialize in the constructor" means that the initial state of the object must be done using setters or the attribution of values to properties after construction? And that in the case of lists it is better that it is null than empty?

  • @ramaral I say you should do with initialization, or in variables, or in the property (C# 6 onwards). This is the simple way to do it. The complicated form is with constructor. It is needed in some cases. But it should not do after construction. Then it would be a mistake. And if necessary, it is one of the reasons to use the constructor. This is explained in the question that I Linkei. There’s no way I think the list should be null. I avoid this as the devil flees from the cross, though very eventually I may do, if it is really useful. Quite rare.

  • I know that’s what you think but, in the specific case of this question, the phrase "the ideal is not to do the boot in the constructor" gives idea of the opposite. By the way, can you tell me if in terms of "compiled" code (C#6) there is a difference between creating the list in the constructor or declaring the property?

  • 1

    In the specific case I would do this way of my answer, unless I was using the 6, which is not the case of the AP and will never be my :P Ideally it is so, only if you have a good reason to use the constructor. You live with good reasons, not in this case. I’ve improved the answer. Is that okay? Thanks for the "complaint":) I will research this, I think if I don’t have to do anything special, it’s the same. It might be an interesting question to ask.

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.