从另一个类定义一个类的变量 [英] Define a variable of one class from another class

查看:174
本文介绍了从另一个类定义一个类的变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 作者 -  AuthorId,AuthorName,DateOfBirth,州,城市,电话。 
Publisher - PublisherId,PublisherName,DateOfBirth,State,City,Phone。
类别 - CategoryId,CategoryName,说明。
Book - BookId,Category,Title,Author,Publisher,Description,Price,ISBN,PublicationDate。

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

解决方案

首先,你需要区分



面向对象的编程(从现在开始只是 OOP )不是关系型



此外,在OOP中有两种

如果你已经实现了两个类 A B ,你可以说 B A ,那么您需要使用继承
。例如, Cat 一个动物
  • 组合。如果你实现了两个类 A B ,你可以说 A 有 c c ,那么您需要使用组合。例如, Car Wheel



  • 现在,请考虑以下规则,并尝试将它们应用于您的特定情况:




    • A Book 拥有作者。答对了!您需要使用组合



    组合通过声明属于



    在您的情况下:

      b $ b {
    public作者作者{get;组; }
    }

    虽然以下代码示例

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

    ...因为OOP 因此,您不会搜索与 Book 相关联的作者,但您可以遍历 Book 来获取<



    换句话说,在OOP中,您的外键 em>是到相关对象的对象引用



    让我们看一个如何在OOP中以正确的方式做事情的摘要想要获得给定书的作者

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

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

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

    AuthorRepository authorRepo = new AuthorRepository();
    author author = authorRepo.GetById(book.AuthorId);

    不要觉得最后的错误在OOP世界?为什么需要执行额外的查询以获取整个 Author 对象?这种感觉非常关系!



    另一方面,将唯一标识符与作者或任何对象,因为您需要唯一地区分每个对象与其他对象,此外,底层数据存储可能通过关系,可能需要存储和检索对象基于他们的主键 /



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




    如果我只想给book对象访问authorid
    而不是别的东西怎么办。因为通过这种方法,我可以访问所有的
    作者的元素。


    欢迎来到 。其使用案例之一是发布信息。或者,换句话说, :



      public interface IUniquelyIdentifiable 
    {
    int Id {get;组; }
    }

    public class作者:IUniquelyIdentifiable
    {
    public int Id {get;组; }
    // ...和其余属性
    }



    您只需要将 IUniquelyIdentifiable 关联到 Book 而不是作者

      public class Book 
    {
    public IUniquelyIdentifiable作者{get;组; }
    }

    ...您还可以设置一个完整的作者

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

    这将隐藏除了 ::: p>

      //如果
    // IUniquelyIdentifiable的实现不是作者$ b,它将为整个变量设置null $ b作者author = book.Author as作者;

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



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


    So following is the set up of different classes that I need to create:

    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.
    

    Now as you can see Author in Book and AuthorId in Author classes are the same.How to achieve this in C#

    解决方案

    First of all, you need to distinguish relational design from object-oriented design.

    Object-oriented programming (from now just OOP) isn't relational but hierarchical, thus, there's no concept of foreign key.

    Also, in OOP there're two kinds of relations between objects:

    • Inheritance. If you've implemented two classes A and B and you can say that B is A, then you need to use inheritance. For example, a Cat is an Animal.
    • Composition. If you've implemented two classes A and B and you can say that A has a B, then you need to use composition. For example, a Car has a Wheel.

    Now take these rules and try to apply them to your particular case:

    • A Book has an Author. Bingo! You need to use composition.

    Composition is expressed by declaring a property of the class that's owned by the enclosing type.

    In your case:

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

    While the following code sample would be wrong:

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

    ...because OOP is hierarchical, thus, you don't search the author associated to the Book, but you traverse Book to get Author's information.

    In other words, in OOP your foreign key is an object reference to the associated object.

    Let's see a summary of how to do things in the right way in OOP when you want to get the Author of a given Book:

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

    Now let's see a wrong sample:

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

    Don't you feel that last wrong sample doesn't feel natural in OOP world? Why you need to perform an additional query to get the whole Author object? This feels very relational!

    In the other hand, there's nothing wrong with associating an unique identifier to Author or any object, because you need to uniquely distinguish each one from others, and, in addition, the underlying data storage might by relational and may need to store and retrieve objects based on their primary key/foreign key.

    OP has also asked on some comment...

    What if I only want to give the book object access only to authorid and nothing else. Because by this method I am able to access all of author's elements.

    Welcome to the world of interfaces. One of their use cases is publishing information. Or, in other words, publishing just what you want to publish:

    public interface IUniquelyIdentifiable
    {
         int Id { get; set; }
    }
    
    public class Author : IUniquelyIdentifiable
    {
         public int Id { get; set; }
         // ...and the rest of properties
    }
    

    Now you just need to associate IUniquelyIdentifiable to Book instead of Author:

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

    ...and you can still set a full Author on Book:

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

    This will hide everything excepting Author.Id, while in some parts of your code you can cast IUniquelyIdentifiable to Author:

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

    BTW you need to be cautious if you're going to use an OR/M, because it may be harder to map your object model to the target relational model.

    IMHO, as a general rule, I wouldn't hide object properties for objects that can be persistent (i.e. those that can be saved to a database).

    这篇关于从另一个类定义一个类的变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆