C#中的CLR屬性、依賴屬性與附加屬性

  • CLR屬性的主要特征

  1. 封裝性

    • 隱藏字段的實現細節

    • 提供對字段的受控訪問

  2. 訪問控制

    • 可單獨設置get/set訪問器的可見性

    • 可創建只讀或只寫屬性

  3. 計算屬性

    • 可以在getter中執行計算邏輯

    • 不需要直接對應一個字段

  4. 驗證邏輯

    • 可以在setter中添加值驗證

    • 可以拋出異常拒絕無效值

  5. 通知機制

    • 可以手動實現屬性變更通知(如INotifyPropertyChanged)

  6. 線程安全

    • 可以添加線程同步邏輯

CLR屬性的實現原理

基本實現

CLR屬性本質上是編譯器生成的"語法糖",編譯后會轉換為方法調用:

// 源代碼
public class Person
{private string _name;public string Name{get { return _name; }set { _name = value; }}
}// 編譯后相當于
public class Person
{private string _name;public string get_Name(){return this._name;}public void set_Name(string value){this._name = value;}
}

自動實現屬性

C# 3.0引入的自動屬性進一步簡化了語法:

public string Name { get; set; }

編譯器會自動生成一個隱藏的私有字段(通常以<Name>k__BackingField命名)和對應的get/set方法。

屬性元數據

在IL(中間語言)層面,屬性是通過以下元數據表示的:

  1. Property表:記錄屬性名稱、類型和訪問器方法

  2. Method表:存儲get/set方法實現

  3. Field表:對于自動屬性,存儲編譯器生成的私有字段

屬性訪問性能

屬性訪問的性能與方法調用相當,因為:

  1. 簡單屬性(get;set;)通常會被JIT內聯優化

  2. 復雜屬性(包含邏輯的)與方法調用開銷相同

  3. 虛屬性(virtual)會有額外的虛方法調用開銷

與依賴屬性的比較

特性CLR屬性依賴屬性
存儲直接存儲在對象中存儲在DependencyObject的全局字典中
綁定支持需實現INotifyPropertyChanged原生支持
動畫支持不支持原生支持
默認值需在構造函數設置可通過元數據指定
繼承不支持支持屬性值繼承
內存占用每個實例都有存儲只有修改過的值才占用內存
適用場景普通業務對象WPF/Silverlight/UWP控件

CLR屬性的高級用法

  1. 索引器

public string this[int index] { get { /*...*/ } set { /*...*/ } }
  1. 表達式體屬性(C# 6+):

public string FullName => $"{FirstName} {LastName}";
  1. 初始化器(C# 6+):

public string Name { get; set; } = "Anonymous";
  1. 只讀自動屬性(C# 6+):

public string Id { get; } = Guid.NewGuid().ToString();

CLR屬性是C#面向對象編程的基礎設施,提供了字段訪問的抽象層,既能保持簡潔的語法,又能提供靈活的控制邏輯。

  • 依賴屬性與附加屬性

依賴屬性(Dependency Property)

實現原理

依賴屬性是WPF/Silverlight/UWP等XAML技術中的核心概念,它擴展了傳統的CLR屬性,提供了更豐富的功能:

  1. 屬性值繼承:子元素可以繼承父元素的屬性值

  2. 數據綁定支持:可以直接作為數據綁定的目標

  3. 動畫支持:可以被動畫系統直接操作

  4. 樣式支持:可以通過樣式設置

  5. 元數據支持:可以指定默認值、驗證回調等

  6. 值優先級系統:多個值源按照優先級決定最終值

實現依賴屬性的關鍵是通過DependencyProperty類和DependencyObject基類:

public class MyControl : DependencyObject
{// 注冊依賴屬性public static readonly DependencyProperty MyPropertyProperty = DependencyProperty.Register("MyProperty",                     // 屬性名稱typeof(string),                  // 屬性類型typeof(MyControl),               // 擁有者類型new PropertyMetadata("默認值"));  // 元數據// CLR包裝器public string MyProperty{get { return (string)GetValue(MyPropertyProperty); }set { SetValue(MyPropertyProperty, value); }}
}

應用場景

  1. 自定義控件開發:為自定義控件添加可綁定、可樣式化的屬性

  2. 數據綁定:作為數據綁定的目標屬性

  3. 動畫:創建可動畫化的屬性

  4. 模板綁定:在控件模板中使用TemplateBinding

  5. 樣式設置:通過樣式設置多個控件的屬性值

附加屬性(Attached Property)

實現原理

附加屬性是一種特殊的依賴屬性,它允許一個類為其他類定義屬性,常用于布局系統和服務模式:

public class GridHelper
{// 注冊附加屬性public static readonly DependencyProperty RowCountProperty =DependencyProperty.RegisterAttached("RowCount",                     // 屬性名稱typeof(int),                     // 屬性類型typeof(GridHelper),              // 擁有者類型new PropertyMetadata(1, OnRowCountChanged)); // 元數據// Get訪問器(必須為public static)public static int GetRowCount(DependencyObject obj){return (int)obj.GetValue(RowCountProperty);}// Set訪問器(必須為public static)public static void SetRowCount(DependencyObject obj, int value){obj.SetValue(RowCountProperty, value);}// 屬性變更回調private static void OnRowCountChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){if (d is Grid grid){// 當RowCount變化時,調整Grid的行定義grid.RowDefinitions.Clear();for (int i = 0; i < (int)e.NewValue; i++){grid.RowDefinitions.Add(new RowDefinition());}}}
}

應用場景

  1. 布局系統:如Grid.Row、Grid.Column等

  2. 服務模式:如ToolTipService.ToolTip、ScrollViewer.IsScrollable等

  3. 行為擴展:為現有控件添加額外功能

  4. 自定義布局面板:創建自己的布局容器時定義布局屬性

兩者比較

特性依賴屬性附加屬性
定義方式在定義類中使用在任何類中定義,可附加到其他對象
注冊方法RegisterRegisterAttached
訪問器實例屬性靜態方法
典型用途為類定義標準屬性為其他類擴展屬性

高級主題

  1. 屬性值優先級:本地值 > 動畫 > 本地樣式 > 觸發器 > 隱式樣式 > 樣式觸發器 > 模板觸發器 > 樣式Setter > 默認值

  2. 屬性變更回調:通過PropertyMetadata指定屬性變化時的處理邏輯

  3. 驗證回調:通過ValidateValueCallback進行值驗證

  4. 強制回調:通過CoerceValueCallback強制屬性值在特定范圍內

依賴屬性和附加屬性是WPF等XAML技術的核心機制,理解它們的原理和用法對于開發復雜的XAML應用程序至關重要。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/84589.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/84589.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/84589.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【mysql】聯合索引和單列索引的區別

區別核心&#xff1a;聯合索引可加速多個字段組合查詢&#xff0c;單列索引只能加速一個字段。 &#x1f539;聯合索引&#xff08;復合索引&#xff09; INDEX(col1, col2, col3)適用范圍&#xff1a; WHERE col1 ... ? WHERE col1 ... AND col2 ... ? WHERE col1 ..…

如何用 HTML 展示計算機代碼

原文&#xff1a;如何用 HTML 展示計算機代碼 | w3cschool筆記 &#xff08;請勿將文章標記為付費&#xff01;&#xff01;&#xff01;&#xff01;&#xff09; 在編程學習和文檔編寫過程中&#xff0c;清晰地展示代碼是一項關鍵技能。HTML 作為網頁開發的基礎語言&#x…

大模型筆記_模型微調

1. 大模型微調的概念 大模型微調&#xff08;Fine-tuning&#xff09;是指在預訓練大語言模型&#xff08;如GPT、BERT、LLaMA等&#xff09;的基礎上&#xff0c;針對特定任務或領域&#xff0c;使用小量的目標領域數據對模型進行進一步訓練&#xff0c;使其更好地適配具體應…

React Native UI 框架與動畫系統:打造專業移動應用界面

React Native UI 框架與動畫系統&#xff1a;打造專業移動應用界面 關鍵要點 UI 框架加速開發&#xff1a;NativeBase、React Native Paper、UI Kitten 和 Tailwind-RN 提供預構建組件&#xff0c;幫助開發者快速創建美觀、一致的界面。動畫提升體驗&#xff1a;React Native…

在QT中使用OpenGL

參考資料&#xff1a; 主頁 - LearnOpenGL CN https://blog.csdn.net/qq_40120946/category_12566573.html 由于OpenGL的大多數實現都是由顯卡廠商編寫的&#xff0c;當產生一個bug時通常可以通過升級顯卡驅動來解決。 OpenGL中的名詞解釋 OpenGL 上下文&#xff08;Conte…

Qt::QueuedConnection詳解

在多線程編程中&#xff0c;線程間的通信是一個關鍵問題。Qt框架提供了強大的信號和槽機制來處理線程通信&#xff0c;其中Qt::QueuedConnection是一種非常有用的連接類型。本文將深入探討Qt::QueuedConnection的原理、使用場景及注意事項。 一、基本概念 Qt::QueuedConnecti…

X86 OpenHarmony5.1.0系統移植與安裝

近期在研究X86鴻蒙,通過一段時間的研究終于成功了,在X86機器上成功啟動了openharmony系統了.下面做個總結和分享 1. 下載源碼 獲取OpenHarmony標準系統源碼 repo init -u https://gitee.com/openharmony/manifest.git -b refs/tags/OpenHarmony-v5.1.0-Release --no-repo-ve…

如何診斷服務器硬盤故障?出現硬盤故障如何處理比較好?

當服務器硬盤出現故障時&#xff0c;及時診斷問題并采取正確的處理方法至關重要。硬盤故障可能導致數據丟失和系統不穩定&#xff0c;影響服務器的正常運行。以下是診斷服務器硬盤故障并處理的最佳實踐&#xff1a; 診斷服務器硬盤故障的步驟 1. 監控警報 硬盤監控工具&#…

vue3提供的hook和通常的函數有什么區別

Vue 3 提供的 hook&#xff08;組合式函數&#xff09; 和普通函數在使用場景、功能和設計目的上有明顯區別&#xff0c;它們是 Vue 3 組合式 API 的核心概念。下面從幾個關鍵維度分析它們的差異&#xff1a; 1. 設計目的不同 Hook&#xff08;組合式函數&#xff09; 專為 Vu…

Spark提交流程

bin/spark-submit --class org.apache.spark.examples.SparkPi --master yarn ./examples/jars/spark-examples_2.12-3.3.1.jar 10 這一句命令實際上是 啟動一個Java程序 java org.apache.spark.deploy.SparkSubmit 并將命令行參數解析到這個類的對應屬性上 因為master給…

Microsoft Copilot Studio - 嘗試一下Agent

1.簡單介紹 Microsoft Copilot Studio以前的名字是Power Virtual Agent(簡稱PVA)。Power Virutal Agent是2019年出現的&#xff0c;是低代碼平臺Power Platform的一部分。當時Generative AI還沒有出現&#xff0c;但是基于已有的Conversation AI技術&#xff0c;即Microsoft L…

【源碼剖析】2-搭建kafka源碼環境

在上篇文章kafka核心概念中&#xff0c;解釋了kafka的核心概念&#xff0c;下面開始進行kafka源碼編譯。為什么學習源碼需要進行源碼編譯呢&#xff0c;我認為主要有兩點&#xff1a; 可以進行debug&#xff0c;跟蹤代碼執行邏輯可以對源碼改動&#xff0c;強化學習學習效果 …

小紅書視頻圖文提取:采集+CV的實戰手記

項目說明&#xff1a;這波視頻&#xff0c;值不值得采&#xff1f; 你有沒有遇到過這樣的場景&#xff1f;老板說&#xff1a;“我們得看看最近小紅書上關于‘旅行’的視頻都說了些什么。”團隊做數據分析的&#xff0c;立馬傻眼&#xff1a;官網打不開、接口抓不著、視頻不能…

Cloudflare 從 Nginx 到 Pingora:性能、效率與安全的全面升級

在互聯網的快速發展中&#xff0c;高性能、高效率和高安全性的網絡服務成為了各大互聯網基礎設施提供商的核心追求。Cloudflare 作為全球領先的互聯網安全和基礎設施公司&#xff0c;近期做出了一個重大技術決策&#xff1a;棄用長期使用的 Nginx&#xff0c;轉而采用其內部開發…

從編輯到安全設置: 如何滿足專業文檔PDF處理需求

隨著數字化辦公的發展&#xff0c;PDF 已成為跨平臺文檔交互的標準格式。無論是在日常辦公、學術研究&#xff0c;還是項目協作中&#xff0c;對 PDF 文件進行高效編輯與管理的需求日益增長。功能全面、操作流暢且無額外負擔的 PDF 編輯工具&#xff0c;它是一款在功能上可與 A…

Kafka消費者組位移重設指南

#作者&#xff1a;張桐瑞 文章目錄 一、Kafka 與傳統消息引擎的核心差異二、重設消費者組位移的核心原因三、重設位移的兩大維度與七種策略四、重設位移的實現方式&#xff08;一&#xff09;Java API 方式&#xff08;二&#xff09;命令行腳本方式&#xff08;Kafka 0.11&am…

分類模型:邏輯回歸

1、針對設計&#xff1a;二分類 Logistic 回歸最初是為二分類問題設計的&#xff0c; Logistic 回歸基于概率&#xff0c;通過 Sigmoid 函數轉換輸入特征的線性組合&#xff0c;將任意實數映射到 [0, 1] 區間內。 通過引入一個決策規則&#xff08;通常是概率的閾值&#xff…

CppCon 2015 學習:C++ WAT

這段代碼展示了 C 中的一些有趣和令人困惑的特性&#xff0c;尤其是涉及數組訪問和某些語法的巧妙之處。讓我們逐個分析&#xff1a; 1. assert(map[“Hello world!”] e;) 這一行看起來很不尋常&#xff0c;因為 map 在這里被用作數組下標訪問器&#xff0c;但是在前面沒有…

vscode自定義主題語法及流程

vscode c/c 主題 DIY 啟用自己的主題(最后步驟) 重啟生效 文件–>首選項–>主題–>顏色主題: 也可以在插件里找到哈 手把手教你制作 在C:\Users\jlh.vscode\extensions下自己創建一個文件夾 里面有兩個文件和一個文件夾 具體內容: package.json: {"name&…

前端傳遞日期范圍(開始時間和結束時間),后端解析及查詢

前端技術&#xff1a;Vue3 TypeScript Element Plus 后端技術&#xff1a;Java Spring Boot MyBatis 應用效果&#xff1a; 原來方案 1、前端日期控件使用 el-date-picker&#xff0c;日期顯示格式和日期值返回格式都為&#xff1a;YYYY-MM-DD <el-form :model"…