[英]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
。
在保留這樣的結構時,您確實需要小心。 盡管將其存儲(存儲在文件,數據庫等中)非常容易,但是您需要確保在讀取數據時重新創建完全相同的對象結構。 想象一下:
現在,首先您需要確定是要按用戶還是按項目持久化,否則您可能會做重復的工作。 恢復持久信息時,需要確保僅創建一個用戶 ! (最好使用唯一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的項目,當你需要知道這個項目是屬於只運行一個誰select
像users.select(x => x.userid == project.userid)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.