簡體   English   中英

存儲對象作為參考?

[英]Storing objects as references?

我不確定自己想要的東西是否可行,這就是我想要的東西:

我有幾個正在存儲的不同對象的集合。 假設有一個Users集合和一個Projects集合。

以下是一些可能看起來像的例子:

public class User
{
    public int UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string EmailAddress { get; set; }

    public List<Project> Projects { get; set;} 
}

public class Project
{
    public int ProjectId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }

    public User Manager { get; set; }
}

如您所見,一個用戶可以有多個項目,而一個項目有一個用戶。

基本上,當我存儲這些項目時,我希望能夠在“用戶”集合中編輯一個“用戶”,並自動更新與該用戶相關的所有項目,以包含有關該用戶的更新信息。 隨后,如果我更新了一個項目,則具有該項目的任何用戶都將自動更新其項目。 喜歡某種方式來存儲對對象而不是值的引用?

有什么辦法嗎?

您在這里擁有的是對象引用 這意味着,只要您指的是同一個對象實例 ),默認情況下一切都會按您期望的那樣工作。

示例(使用您的課程):

User u = new User();
Project p = new Project();
p.Manager = u;
u.Projects.Add(p);

這將創建一個空用戶和一個空項目。 項目引用用戶,用戶的項目列表引用項目。

現在,您更改用戶和項目的名稱:

u.FirstName = "Test";
u.LastName = "User";

這將使您獲得以下結果:

Console.WriteLine("{0} {1}", p.Manager.FirstName, p.Manager.LastName);
=> Test User

您現在可以做的另一件事是:

User userInfo = p.Manager;
userInfo.EMailAddress = "test@company.org";

這將反映您訪問已分配用戶對象的任何方式,因為所有這些“變量”都“指向”同一對象實例(它們引用內存中的同一對象)。

您甚至可以將對象引用傳遞給另一個方法:

public void ChangeProjectManagerEmail(Project theProject, string newEMail)
{
    theProject.Manager.EMailAddress = newEMail;
}

像這樣調用上面的方法:

ChangeProjectManagerEmail(p, "hello@world.com");

將導致以下結果:

Console.WriteLine(u.EMailAddress);
=> hello@world.com

什么是行不通的

User anotherUser = new User();
anotherUser.UserId = 5;

Console.WriteLine(p.Manager.UserId);

這將輸出0 ,因為任何其他對象均未引用新用戶anotherUser

在保留這樣的結構時,您確實需要小心。 盡管將其存儲(存儲在文件,數據庫等中)非常容易,但是您需要確保在讀取數據時重新創建完全相同的對象結構。 想象一下:

  • 項目1參考用戶u1
  • 項目2參考用戶u1
  • u1引用項目1和2

現在,首先您需要確定是要按用戶還是按項目持久化,否則您可能會做重復的工作。 恢復持久信息時,需要確保創建一個用戶 (最好使用唯一ID來檢查用戶是否已還原)。 否則,您最終將獲得兩個具有相同信息的不同User對象,並且您會奇怪為什么更改用戶僅反映一個項目。 最糟糕的情況是,在更改用戶信息之后,您將最終獲得兩個具有相同ID但存儲中信息不同的用戶。


所有這一切說: 小心! 就交叉引用而言,您的對象結構有些危險。 現在,很可能將項目添加到引用完全不同的用戶作為其管理員的用戶。 例:

User user1 = new User();
// Initialize ID, name, etc.

User user2 = new User();
// Initialize ID, name, etc.

Project p = new Project();
// Initialize stuff
p.Manager = user2;

user1.Projects.Add(p);

在這里看到問題了嗎?

您可以實現觀察者設計模式,以在特定對象發生更改時通知“觀察者”。

“觀察者設計模式要求在一個觀察者和一個提供者之間進行划分,該觀察者注冊通知,而提供者監視數據並將通知發送給一個或多個觀察者。”

請參見點網中此模式的實現:

https://msdn.microsoft.com/zh-CN/library/ff506346(v=vs.110).aspx

https://msdn.microsoft.com/zh-CN/library/ee817669.aspx

如果只希望數據庫級別,則可以創建觸發器“ ON UPDATE”以進行所需的更改。

你為什么不只是保持用戶ID的項目,當你需要知道這個項目是屬於只運行一個誰selectusers.select(x => x.userid == project.userid)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM