从一个类定义另一个类的变量
本文关键字:定义 另一个 变量 一个 | 更新日期: 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中对象之间有两种关系:
-
。如果您实现了
A
和B
两个类,并且您可以说B
是A
,那么您需要使用继承。例如,Cat
为,Animal
为 。 - 作文。如果你已经实现了
A
和B
两个类,你可以说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中,外键是对关联对象的对象引用。
让我们看看如何在OOP中以正确的方式做事,当你想获得给定Book
的Author
:
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,您需要小心,因为将您的对象模型映射到目标关系模型可能会更困难。
恕我直言,作为一般规则,我不会隐藏对象属性的对象可以是持久的(即那些可以保存到数据库)。