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

本文关键字:定义 另一个 变量 一个 | 更新日期: 2023-09-27 18:01:21

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

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中的Author和Author类中的AuthorId是一样的。如何在c#中实现

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

您的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();

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

面向对象编程(从现在开始只是OOP)不是关系的,而是分层的,因此,没有外键的概念。

同样,在OOP中对象之间有两种关系:

  • 。如果您实现了AB两个类,并且您可以说BA,那么您需要使用继承。例如,Cat Animal
  • 作文。如果你已经实现了AB两个类,你可以说A 一个B,那么你需要使用组合。例如,CarWheel

现在把这些规则应用到你的特殊情况中:

  • Book Author。宾果!你需要使用合成

复合是通过声明类的属性来表示的,该属性为封闭类型所拥有。

在你的例子中:

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

下面的代码示例是错误的:

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

…因为OOP 是分层的,因此,您不搜索与Book相关的作者,而是遍历Book来获取Author的信息

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

让我们看看如何在OOP中以正确的方式做事,当你想获得给定BookAuthor:

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

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

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

你不觉得最后一个错误的示例在OOP世界中感觉不自然吗?为什么需要执行一个额外的查询来获取整个Author对象?这感觉很有关系!

另一方面,将唯一标识符与Author或任何对象相关联并没有什么问题,因为您需要唯一地区分每个对象,此外,底层数据存储可能是关系型的,并且可能需要根据对象的主键/外键来存储和检索对象。

OP也问了一些评论…

如果我只想给图书对象只给authorid访问权限怎么办没有别的了。因为通过这种方法,我可以访问所有作者的元素。

欢迎来到接口的世界。它们的一个用例是发布信息。或者,换句话说,发布您想要发布的内容:

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

…你还可以在Book上设置一个完整的Author:

Book book = new Book();
book.Author = new Author();

这将隐藏除Author.Id以外的所有内容,而在代码的某些部分,您可以将IUniquelyIdentifiable转换为Author:

// It'll set null to the whole variable if the 
// implementation of IUniquelyIdentifiable isn't Author
Author author = book.Author as Author;

顺便说一句,如果您打算使用OR/M,您需要小心,因为将您的对象模型映射到目标关系模型可能会更困难。

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