从另一个类定义一个类的变量

时间:2016-08-07 14:59:29

标签: c# class oop

以下是我需要创建的不同类的设置:

Author – AuthorId, AuthorName, DateOfBirth, State, City, Phone.
Publisher – PublisherId, PublisherName, DateOfBirth, State, City, Phone.
Category – CategoryId, CategoryName, Description.
Book – BookId, Category, Title, Author, Publisher, Description, Price, ISBN, PublicationDate.

现在您可以看到作者在Book和AuthorId中的作者类是一样的。如何在C#中实现这一点

2 个答案:

答案 0 :(得分:5)

您的Book对象可能会引用该类中的Author,如下所示。

public class Author
{
    public int AuthorId { get; set; }
    public string AuthorName { get; set; }
}

public class Book
{
   private Author _author { get; set; }

   public Book(Author author)
   {
     _author = author;
   }

   public void PrintBookAuthor()
   {
     Console.WriteLine(_author.AuthorName);
   }
}

然后设置:

Author author = new Author();
author.AuthorName = "Darren Davies";

Book programmingBook = new Book(author);
programmingBook.PrintBookAuthor();

答案 1 :(得分:2)

首先,您需要将关系设计面向对象设计区分开来。

面向对象的编程(从现在开始只是 OOP )不是关系型的,而是层次结构,因此,那里有没有外键的概念

此外,在OOP中,对象之间存在两种关系

  • 继承即可。如果您已经实施了两个类AB,并且您可以说BA,那么您需要使用继承 。例如,Cat Animal
  • 组合物即可。如果您已经实施了两个类AB,并且您可以说A 一个B,那么您需要使用组合物。例如,Car有一个Wheel

现在采用这些规则并尝试将它们应用于您的特定情况:

  • Book Author。答对了!您需要使用组合

通过声明由封闭类型拥有的类的属性来表达组合。

在你的情况下:

public class Book
{
     public Author Author { get; set; }
}

以下代码示例错误

public class Book
{
    public int AuthorId { get; set; }
}

...因为OOP 是分层,因此,您不会搜索与Book相关联的作者,但是您将Book遍历到获取Author的信息

换句话说,在OOP中,外键是关联对象的对象引用

如果您希望获得给定Author的{​​{1}},请在OOP中查看如何以正确方式执行操作的摘要:

Book

现在让我们看一下错误的示例:

BookRepository bookRepo = new BookRepository();
Book book = bookRepo.GetById(302);
Author author = book.Author;

你不觉得最后错误的样本在OOP世界中并不自然吗?为什么需要执行其他查询来获取整个BookRepository bookRepo = new BookRepository(); Book book = bookRepo.GetById(302); AuthorRepository authorRepo = new AuthorRepository(); Author author = authorRepo.GetById(book.AuthorId); 对象?这感觉非常关系!

另一方面,将唯一标识符与Author或任何对象相关联并没有错,因为您需要将每个标识符与其他标识符进行唯一区分,此外还有基础数据存储空间可能是关系型的,可能需要根据主键 / 外键来存储和检索对象。

OP还询问了一些评论......

  

如果我只想让图书对象只能访问authorid,该怎么办?   没有别的。因为通过这种方法,我能够访问所有   作者的要素。

欢迎来到 interfaces 的世界。其中一个用例是发布信息。或者,换句话说,只发布您要发布的内容

Author

现在您只需将public interface IUniquelyIdentifiable { int Id { get; set; } } public class Author : IUniquelyIdentifiable { public int Id { get; set; } // ...and the rest of properties } IUniquelyIdentifiable关联,而不是Book

Author

...您仍然可以在public class Book { public IUniquelyIdentifiable Author { get; set; } } 上设置完整的Author

Book

这将隐藏Book book = new Book(); book.Author = new Author(); 之外的所有内容,而在代码的某些部分,您可以Author.Id投放到IUniquelyIdentifiable

Author
如果您要使用OR/M,则需要谨慎,因为将对象模型映射到目标关系模型可能更难。

恕我直言,作为一般规则,我不会隐藏可以持久化的对象的对象属性(即那些可以保存到数据库中的对象)。