[{"data":1,"prerenderedAt":2324},["ShallowReactive",2],{"navigation_docs":3,"-tu-hoc-generic-constraint-variance":420,"-tu-hoc-generic-constraint-variance-surround":2319},[4,153],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":26},"Phỏng vấn .NET","i-lucide-briefcase","\u002Fphong-van","1.phong-van",[10,27,66,111,128],{"title":11,"icon":12,"path":13,"stem":14,"children":15,"page":26},"Tổng quan","i-lucide-compass","\u002Fphong-van\u002Ftong-quan","1.phong-van\u002F1.tong-quan",[16,21],{"title":17,"path":18,"stem":19,"icon":20},"Thị trường HCM","\u002Fphong-van\u002Ftong-quan\u002Fthi-truong","1.phong-van\u002F1.tong-quan\u002F1.thi-truong","i-lucide-trending-up",{"title":22,"path":23,"stem":24,"icon":25},"Lộ trình 7 ngày","\u002Fphong-van\u002Ftong-quan\u002Flo-trinh","1.phong-van\u002F1.tong-quan\u002F2.lo-trinh","i-lucide-calendar-days",false,{"title":22,"icon":25,"path":28,"stem":29,"children":30,"page":26},"\u002Fphong-van\u002Flo-trinh","1.phong-van\u002F2.lo-trinh",[31,36,41,46,51,56,61],{"title":32,"path":33,"stem":34,"icon":35},"Ngày 1 — C# cơ bản","\u002Fphong-van\u002Flo-trinh\u002Fngay-1-csharp-co-ban","1.phong-van\u002F2.lo-trinh\u002F1.ngay-1-csharp-co-ban","i-lucide-1",{"title":37,"path":38,"stem":39,"icon":40},"Ngày 2 — OOP và SOLID","\u002Fphong-van\u002Flo-trinh\u002Fngay-2-oop-solid","1.phong-van\u002F2.lo-trinh\u002F2.ngay-2-oop-solid","i-lucide-2",{"title":42,"path":43,"stem":44,"icon":45},"Ngày 3 — C# nâng cao","\u002Fphong-van\u002Flo-trinh\u002Fngay-3-csharp-nang-cao","1.phong-van\u002F2.lo-trinh\u002F3.ngay-3-csharp-nang-cao","i-lucide-3",{"title":47,"path":48,"stem":49,"icon":50},"Ngày 4 — Database và SQL","\u002Fphong-van\u002Flo-trinh\u002Fngay-4-database-sql","1.phong-van\u002F2.lo-trinh\u002F4.ngay-4-database-sql","i-lucide-4",{"title":52,"path":53,"stem":54,"icon":55},"Ngày 5 — ASP.NET Core và EF Core","\u002Fphong-van\u002Flo-trinh\u002Fngay-5-aspnet-efcore","1.phong-van\u002F2.lo-trinh\u002F5.ngay-5-aspnet-efcore","i-lucide-5",{"title":57,"path":58,"stem":59,"icon":60},"Ngày 6 — DSA coding","\u002Fphong-van\u002Flo-trinh\u002Fngay-6-dsa","1.phong-van\u002F2.lo-trinh\u002F6.ngay-6-dsa","i-lucide-6",{"title":62,"path":63,"stem":64,"icon":65},"Ngày 7 — Mock và HR","\u002Fphong-van\u002Flo-trinh\u002Fngay-7-mock-interview","1.phong-van\u002F2.lo-trinh\u002F7.ngay-7-mock-interview","i-lucide-7",{"title":67,"icon":68,"path":69,"stem":70,"children":71,"page":26},"Ngân hàng câu hỏi","i-lucide-database","\u002Fphong-van\u002Fngan-hang-cau-hoi","1.phong-van\u002F3.ngan-hang-cau-hoi",[72,77,82,87,92,97,102,107],{"title":73,"path":74,"stem":75,"icon":76},"C# (60+ câu)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fcsharp","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F1.csharp","i-lucide-hash",{"title":78,"path":79,"stem":80,"icon":81},"OOP và SOLID (40+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Foop","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F2.oop","i-lucide-shapes",{"title":83,"path":84,"stem":85,"icon":86},"SQL (40+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fsql","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F3.sql","i-lucide-database-zap",{"title":88,"path":89,"stem":90,"icon":91},"ASP.NET và EF (50+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Faspnet-ef","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F4.aspnet-ef","i-lucide-server",{"title":93,"path":94,"stem":95,"icon":96},"DSA và Coding (30+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fdsa-coding","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F5.dsa-coding","i-lucide-binary",{"title":98,"path":99,"stem":100,"icon":101},"HR và Soft skill (25+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fhr-behavior","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F6.hr-behavior","i-lucide-users",{"title":103,"path":104,"stem":105,"icon":106},"Design Pattern (55+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fdesign-pattern","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F7.design-pattern","i-lucide-puzzle",{"title":108,"path":109,"stem":110,"icon":91},"ASP.NET MVC và Web API","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Faspnet-mvc-webapi","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F8.aspnet-mvc-webapi",{"title":112,"itle":113,"icon":114,"path":115,"stem":116,"children":117,"page":26},"Tai Lieu","Tài liệu và Cheat sheet","i-lucide-book-marked","\u002Fphong-van\u002Ftai-lieu","1.phong-van\u002F4.tai-lieu",[118,123],{"title":119,"path":120,"stem":121,"icon":122},"Cheat Sheet","\u002Fphong-van\u002Ftai-lieu\u002Fcheatsheet","1.phong-van\u002F4.tai-lieu\u002F1.cheatsheet","i-lucide-clipboard-list",{"title":124,"path":125,"stem":126,"icon":127},"Nguồn tham khảo","\u002Fphong-van\u002Ftai-lieu\u002Fnguon","1.phong-van\u002F4.tai-lieu\u002F2.nguon","i-lucide-link",{"title":129,"icon":130,"path":131,"stem":132,"children":133,"page":26},"Phỏng vấn English","i-lucide-globe","\u002Fphong-van\u002Fenglish-interview","1.phong-van\u002F5.english-interview",[134,138,143,148],{"title":135,"path":136,"stem":137,"icon":130},"Tổng quan English","\u002Fphong-van\u002Fenglish-interview\u002Ftong-quan","1.phong-van\u002F5.english-interview\u002F1.tong-quan",{"title":139,"path":140,"stem":141,"icon":142},"Vocabulary","\u002Fphong-van\u002Fenglish-interview\u002Fvocabulary","1.phong-van\u002F5.english-interview\u002F2.vocabulary","i-lucide-book-a",{"title":144,"path":145,"stem":146,"icon":147},"Technical Q và A (EN)","\u002Fphong-van\u002Fenglish-interview\u002Ftechnical-en","1.phong-van\u002F5.english-interview\u002F3.technical-en","i-lucide-code",{"title":149,"path":150,"stem":151,"icon":152},"Behavioral (EN)","\u002Fphong-van\u002Fenglish-interview\u002Fbehavioral-en","1.phong-van\u002F5.english-interview\u002F4.behavioral-en","i-lucide-message-square-text",{"title":154,"icon":155,"path":156,"stem":157,"children":158},"Tự học","i-lucide-graduation-cap","\u002Ftu-hoc","2.tu-hoc",[159,161,287,310,333,357,384],{"title":154,"path":156,"stem":160,"icon":155},"2.tu-hoc\u002Findex",{"title":162,"icon":68,"path":163,"stem":164,"children":165},"Database","\u002Ftu-hoc\u002Fdatabase","2.tu-hoc\u002F1.database\u002Findex",[166,167,197,222,243,248],{"title":162,"path":163,"stem":164,"icon":68},{"title":168,"icon":91,"path":169,"stem":170,"children":171,"page":26},"SQL Server","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server","2.tu-hoc\u002F1.database\u002F2.sql-server",[172,177,182,187,192],{"title":173,"path":174,"stem":175,"icon":176},"1. Giới thiệu và Cài đặt","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F1.gioi-thieu-cai-dat","i-lucide-play-circle",{"title":178,"path":179,"stem":180,"icon":181},"2. Cú pháp cơ bản","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fcu-phap-co-ban","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F2.cu-phap-co-ban","i-lucide-code-2",{"title":183,"path":184,"stem":185,"icon":186},"3. Truy vấn nâng cao","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Ftruy-van-nang-cao","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F3.truy-van-nang-cao","i-lucide-git-merge",{"title":188,"path":189,"stem":190,"icon":191},"4. Đặc thù và Performance","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fdac-thu-performance","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F4.dac-thu-performance","i-lucide-gauge",{"title":193,"path":194,"stem":195,"icon":196},"5. Q và A phỏng vấn","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fcau-hoi-phong-van","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F5.cau-hoi-phong-van","i-lucide-message-circle-question",{"title":198,"icon":199,"path":200,"stem":201,"children":202,"page":26},"PostgreSQL","i-simple-icons-postgresql","\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql","2.tu-hoc\u002F1.database\u002F3.postgresql",[203,206,209,212,215,218],{"title":173,"path":204,"stem":205,"icon":176},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F1.gioi-thieu-cai-dat",{"title":178,"path":207,"stem":208,"icon":181},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fcu-phap-co-ban","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F2.cu-phap-co-ban",{"title":183,"path":210,"stem":211,"icon":186},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Ftruy-van-nang-cao","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F3.truy-van-nang-cao",{"title":188,"path":213,"stem":214,"icon":191},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fdac-thu-performance","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F4.dac-thu-performance",{"title":193,"path":216,"stem":217,"icon":196},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fcau-hoi-phong-van","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F5.cau-hoi-phong-van",{"title":219,"path":220,"stem":221,"icon":96},"6. Tích hợp C# và Postgres","\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Ftich-hop-csharp","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F6.tich-hop-csharp",{"title":223,"icon":224,"path":225,"stem":226,"children":227,"page":26},"MySQL","i-simple-icons-mysql","\u002Ftu-hoc\u002Fdatabase\u002Fmysql","2.tu-hoc\u002F1.database\u002F4.mysql",[228,231,234,237,240],{"title":173,"path":229,"stem":230,"icon":176},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F1.database\u002F4.mysql\u002F1.gioi-thieu-cai-dat",{"title":178,"path":232,"stem":233,"icon":181},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fcu-phap-co-ban","2.tu-hoc\u002F1.database\u002F4.mysql\u002F2.cu-phap-co-ban",{"title":183,"path":235,"stem":236,"icon":186},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Ftruy-van-nang-cao","2.tu-hoc\u002F1.database\u002F4.mysql\u002F3.truy-van-nang-cao",{"title":188,"path":238,"stem":239,"icon":191},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fdac-thu-performance","2.tu-hoc\u002F1.database\u002F4.mysql\u002F4.dac-thu-performance",{"title":193,"path":241,"stem":242,"icon":196},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fcau-hoi-phong-van","2.tu-hoc\u002F1.database\u002F4.mysql\u002F5.cau-hoi-phong-van",{"title":244,"path":245,"stem":246,"icon":247},"So sánh 3 RDBMS","\u002Ftu-hoc\u002Fdatabase\u002Fso-sanh","2.tu-hoc\u002F1.database\u002F5.so-sanh","i-lucide-columns-3",{"title":249,"path":250,"stem":251,"children":252,"icon":254},"Supabase (BaaS)","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase","2.tu-hoc\u002F1.database\u002F6.supabase\u002Findex",[253,255,259,264,269,274,278,283],{"title":249,"path":250,"stem":251,"icon":254},"i-simple-icons-supabase",{"title":256,"path":257,"stem":258,"icon":68},"1. Database","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fdatabase","2.tu-hoc\u002F1.database\u002F6.supabase\u002F1.database",{"title":260,"path":261,"stem":262,"icon":263},"2. Authentication","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fauthentication","2.tu-hoc\u002F1.database\u002F6.supabase\u002F2.authentication","i-lucide-key",{"title":265,"path":266,"stem":267,"icon":268},"3. Storage & Realtime","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fstorage-realtime","2.tu-hoc\u002F1.database\u002F6.supabase\u002F3.storage-realtime","i-lucide-zap",{"title":270,"path":271,"stem":272,"icon":273},"4. Edge Functions & AI","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Ffunctions-ai","2.tu-hoc\u002F1.database\u002F6.supabase\u002F4.functions-ai","i-lucide-brain",{"title":275,"path":276,"stem":277,"icon":181},"5. API & SDKs","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fapi-sdk","2.tu-hoc\u002F1.database\u002F6.supabase\u002F5.api-sdk",{"title":279,"path":280,"stem":281,"icon":282},"6. Platform & Deploy","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fplatform-deploy","2.tu-hoc\u002F1.database\u002F6.supabase\u002F6.platform-deploy","i-lucide-cloud",{"title":284,"path":285,"stem":286,"icon":196},"7. Interview & Q&A","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Finterview","2.tu-hoc\u002F1.database\u002F6.supabase\u002F7.interview",{"title":288,"icon":289,"path":290,"stem":291,"children":292},"TypeScript","i-simple-icons-typescript","\u002Ftu-hoc\u002Ftypescript","2.tu-hoc\u002F2.typescript\u002Findex",[293,294,297,301,306],{"title":288,"path":290,"stem":291,"icon":289},{"title":173,"path":295,"stem":296,"icon":176},"\u002Ftu-hoc\u002Ftypescript\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F2.typescript\u002F1.gioi-thieu-cai-dat",{"title":298,"path":299,"stem":300,"icon":81},"2. Type System","\u002Ftu-hoc\u002Ftypescript\u002Ftype-system","2.tu-hoc\u002F2.typescript\u002F2.type-system",{"title":302,"path":303,"stem":304,"icon":305},"3. Advanced types","\u002Ftu-hoc\u002Ftypescript\u002Fadvanced-types","2.tu-hoc\u002F2.typescript\u002F3.advanced-types","i-lucide-braces",{"title":307,"path":308,"stem":309,"icon":196},"4. Q và A phỏng vấn","\u002Ftu-hoc\u002Ftypescript\u002Fcau-hoi-phong-van","2.tu-hoc\u002F2.typescript\u002F4.cau-hoi-phong-van",{"title":311,"icon":81,"path":312,"stem":313,"children":314},"OOP","\u002Ftu-hoc\u002Foop","2.tu-hoc\u002F3.oop\u002Findex",[315,316,321,326,330],{"title":311,"path":312,"stem":313,"icon":81},{"title":317,"path":318,"stem":319,"icon":320},"1. Bốn tính chất","\u002Ftu-hoc\u002Foop\u002F4-tinh-chat","2.tu-hoc\u002F3.oop\u002F1.4-tinh-chat","i-lucide-circle-dot",{"title":322,"path":323,"stem":324,"icon":325},"2. SOLID","\u002Ftu-hoc\u002Foop\u002Fsolid","2.tu-hoc\u002F3.oop\u002F2.solid","i-lucide-shield",{"title":327,"path":328,"stem":329,"icon":106},"3. Design Pattern","\u002Ftu-hoc\u002Foop\u002Fdesign-pattern","2.tu-hoc\u002F3.oop\u002F3.design-pattern",{"title":307,"path":331,"stem":332,"icon":196},"\u002Ftu-hoc\u002Foop\u002Fcau-hoi-phong-van","2.tu-hoc\u002F3.oop\u002F4.cau-hoi-phong-van",{"title":334,"icon":305,"path":335,"stem":336,"children":337},"Generic","\u002Ftu-hoc\u002Fgeneric","2.tu-hoc\u002F4.generic\u002Findex",[338,339,344,349,354],{"title":334,"path":335,"stem":336,"icon":305},{"title":340,"path":341,"stem":342,"icon":343},"1. Khái niệm và cú pháp","\u002Ftu-hoc\u002Fgeneric\u002Fkhai-niem","2.tu-hoc\u002F4.generic\u002F1.khai-niem","i-lucide-book",{"title":345,"path":346,"stem":347,"icon":348},"2. Constraint và Variance","\u002Ftu-hoc\u002Fgeneric\u002Fconstraint-variance","2.tu-hoc\u002F4.generic\u002F2.constraint-variance","i-lucide-filter",{"title":350,"path":351,"stem":352,"icon":353},"3. C# vs TS","\u002Ftu-hoc\u002Fgeneric\u002Fso-sanh","2.tu-hoc\u002F4.generic\u002F3.so-sanh","i-lucide-git-compare",{"title":307,"path":355,"stem":356,"icon":196},"\u002Ftu-hoc\u002Fgeneric\u002Fcau-hoi-phong-van","2.tu-hoc\u002F4.generic\u002F4.cau-hoi-phong-van",{"title":358,"icon":359,"path":360,"stem":361,"children":362},"Nuxt 4","i-simple-icons-nuxt","\u002Ftu-hoc\u002Fnuxt-4","2.tu-hoc\u002F5.nuxt-4\u002Findex",[363,364,367,372,376,379],{"title":358,"path":360,"stem":361,"icon":359},{"title":173,"path":365,"stem":366,"icon":176},"\u002Ftu-hoc\u002Fnuxt-4\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F5.nuxt-4\u002F1.gioi-thieu-cai-dat",{"title":368,"path":369,"stem":370,"icon":371},"2. Routing và Rendering","\u002Ftu-hoc\u002Fnuxt-4\u002Frouting-rendering","2.tu-hoc\u002F5.nuxt-4\u002F2.routing-rendering","i-lucide-route",{"title":373,"path":374,"stem":375,"icon":91},"3. Data và Server","\u002Ftu-hoc\u002Fnuxt-4\u002Fdata-server","2.tu-hoc\u002F5.nuxt-4\u002F3.data-server",{"title":307,"path":377,"stem":378,"icon":196},"\u002Ftu-hoc\u002Fnuxt-4\u002Fcau-hoi-phong-van","2.tu-hoc\u002F5.nuxt-4\u002F4.cau-hoi-phong-van",{"title":380,"path":381,"stem":382,"icon":383},"5. Practical Todo App","\u002Ftu-hoc\u002Fnuxt-4\u002Fpractical-todo-app","2.tu-hoc\u002F5.nuxt-4\u002F5.practical-todo-app","i-lucide-check-square",{"title":385,"path":386,"stem":387,"children":388,"icon":390},"Tailwind CSS","\u002Ftu-hoc\u002Ftailwindcss","2.tu-hoc\u002F6.tailwindcss\u002Findex",[389,391,396,401,406,411,416],{"title":385,"path":386,"stem":387,"icon":390},"i-simple-icons-tailwindcss",{"title":392,"path":393,"stem":394,"icon":395},"1. Layout & Spacing","\u002Ftu-hoc\u002Ftailwindcss\u002Flayout-spacing","2.tu-hoc\u002F6.tailwindcss\u002F1.layout-spacing","i-lucide-layout",{"title":397,"path":398,"stem":399,"icon":400},"2. Typography & Colors","\u002Ftu-hoc\u002Ftailwindcss\u002Ftypography-colors","2.tu-hoc\u002F6.tailwindcss\u002F2.typography-colors","i-lucide-type",{"title":402,"path":403,"stem":404,"icon":405},"3. Interactive & Effects","\u002Ftu-hoc\u002Ftailwindcss\u002Finteractive-effects","2.tu-hoc\u002F6.tailwindcss\u002F3.interactive-effects","i-lucide-sparkles",{"title":407,"path":408,"stem":409,"icon":410},"4. Responsive & Dark Mode","\u002Ftu-hoc\u002Ftailwindcss\u002Fresponsive-darkmode","2.tu-hoc\u002F6.tailwindcss\u002F4.responsive-darkmode","i-lucide-monitor-smartphone",{"title":412,"path":413,"stem":414,"icon":415},"5. Customization & Theme","\u002Ftu-hoc\u002Ftailwindcss\u002Fcustomization","2.tu-hoc\u002F6.tailwindcss\u002F5.customization","i-lucide-settings-2",{"title":417,"path":418,"stem":419,"icon":181},"6. Practical Projects","\u002Ftu-hoc\u002Ftailwindcss\u002Fpractical-projects","2.tu-hoc\u002F6.tailwindcss\u002F6.practical-projects",{"id":421,"title":422,"body":423,"description":2312,"extension":2313,"links":2314,"meta":2315,"navigation":2316,"path":346,"seo":2317,"stem":347,"__hash__":2318},"docs\u002F2.tu-hoc\u002F4.generic\u002F2.constraint-variance.md","Generic — Constraint và Variance",{"type":424,"value":425,"toc":2291},"minimark",[426,431,435,440,644,648,1061,1122,1126,1130,1211,1215,1518,1522,1544,1548,1565,1568,1610,1614,1644,1658,1665,1703,1709,1747,1778,1782,1789,1981,1992,2110,2198,2202,2209,2220,2223,2227,2271,2280,2287],[427,428,430],"h2",{"id":429},"_1-generic-constraint","1. Generic constraint",[432,433,434],"p",{},"Constraint hạn chế type parameter T phải thoả điều kiện gì.",[436,437,439],"h3",{"id":438},"constraint-c","Constraint C#",[441,442,443,508,550,608],"tabs",{},[444,445,448],"div",{"icon":446,"label":447},"i-simple-icons-csharp","Reference \u002F Value",[449,450,455],"pre",{"className":451,"code":452,"language":453,"meta":454,"style":454},"language-csharp shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F T là reference type\npublic class Cache\u003CT> where T : class { }\n\n\u002F\u002F T là value type (struct)\npublic class Counter\u003CT> where T : struct { }\n\n\u002F\u002F T là non-nullable value type\npublic class CounterNonNull\u003CT> where T : struct, System.Enum { }\n","csharp","",[456,457,458,466,472,479,485,491,496,502],"code",{"__ignoreMap":454},[459,460,463],"span",{"class":461,"line":462},"line",1,[459,464,465],{},"\u002F\u002F T là reference type\n",[459,467,469],{"class":461,"line":468},2,[459,470,471],{},"public class Cache\u003CT> where T : class { }\n",[459,473,475],{"class":461,"line":474},3,[459,476,478],{"emptyLinePlaceholder":477},true,"\n",[459,480,482],{"class":461,"line":481},4,[459,483,484],{},"\u002F\u002F T là value type (struct)\n",[459,486,488],{"class":461,"line":487},5,[459,489,490],{},"public class Counter\u003CT> where T : struct { }\n",[459,492,494],{"class":461,"line":493},6,[459,495,478],{"emptyLinePlaceholder":477},[459,497,499],{"class":461,"line":498},7,[459,500,501],{},"\u002F\u002F T là non-nullable value type\n",[459,503,505],{"class":461,"line":504},8,[459,506,507],{},"public class CounterNonNull\u003CT> where T : struct, System.Enum { }\n",[444,509,511],{"icon":446,"label":510},"Constructor \u002F Default",[449,512,514],{"className":451,"code":513,"language":453,"meta":454,"style":454},"\u002F\u002F T có constructor không tham số\npublic class Factory\u003CT> where T : new() {\n    public T Create() => new T();\n}\n\n\u002F\u002F Combine\npublic class Repository\u003CT> where T : class, IEntity, new() { }\n",[456,515,516,521,526,531,536,540,545],{"__ignoreMap":454},[459,517,518],{"class":461,"line":462},[459,519,520],{},"\u002F\u002F T có constructor không tham số\n",[459,522,523],{"class":461,"line":468},[459,524,525],{},"public class Factory\u003CT> where T : new() {\n",[459,527,528],{"class":461,"line":474},[459,529,530],{},"    public T Create() => new T();\n",[459,532,533],{"class":461,"line":481},[459,534,535],{},"}\n",[459,537,538],{"class":461,"line":487},[459,539,478],{"emptyLinePlaceholder":477},[459,541,542],{"class":461,"line":493},[459,543,544],{},"\u002F\u002F Combine\n",[459,546,547],{"class":461,"line":498},[459,548,549],{},"public class Repository\u003CT> where T : class, IEntity, new() { }\n",[444,551,553],{"icon":446,"label":552},"Interface \u002F Base class",[449,554,556],{"className":451,"code":555,"language":453,"meta":454,"style":454},"\u002F\u002F T implement IComparable\u003CT>\npublic static T Max\u003CT>(T a, T b) where T : IComparable\u003CT>\n    => a.CompareTo(b) >= 0 ? a : b;\n\n\u002F\u002F T kế thừa Animal\npublic class AnimalCage\u003CT> where T : Animal { }\n\n\u002F\u002F T là static interface (C# 11+) — operator\npublic static T Sum\u003CT>(IEnumerable\u003CT> nums) where T : INumber\u003CT>\n    => nums.Aggregate(T.Zero, (a, b) => a + b);\n",[456,557,558,563,568,573,577,582,587,591,596,602],{"__ignoreMap":454},[459,559,560],{"class":461,"line":462},[459,561,562],{},"\u002F\u002F T implement IComparable\u003CT>\n",[459,564,565],{"class":461,"line":468},[459,566,567],{},"public static T Max\u003CT>(T a, T b) where T : IComparable\u003CT>\n",[459,569,570],{"class":461,"line":474},[459,571,572],{},"    => a.CompareTo(b) >= 0 ? a : b;\n",[459,574,575],{"class":461,"line":481},[459,576,478],{"emptyLinePlaceholder":477},[459,578,579],{"class":461,"line":487},[459,580,581],{},"\u002F\u002F T kế thừa Animal\n",[459,583,584],{"class":461,"line":493},[459,585,586],{},"public class AnimalCage\u003CT> where T : Animal { }\n",[459,588,589],{"class":461,"line":498},[459,590,478],{"emptyLinePlaceholder":477},[459,592,593],{"class":461,"line":504},[459,594,595],{},"\u002F\u002F T là static interface (C# 11+) — operator\n",[459,597,599],{"class":461,"line":598},9,[459,600,601],{},"public static T Sum\u003CT>(IEnumerable\u003CT> nums) where T : INumber\u003CT>\n",[459,603,605],{"class":461,"line":604},10,[459,606,607],{},"    => nums.Aggregate(T.Zero, (a, b) => a + b);\n",[444,609,611],{"icon":446,"label":610},"Linked params",[449,612,614],{"className":451,"code":613,"language":453,"meta":454,"style":454},"\u002F\u002F T phải là U hoặc subtype của U\npublic class Container\u003CT, U> where T : U { }\n\npublic class Notifier\u003CT> where T : Animal {\n    public void Notify\u003CU>(U pet) where U : T { ... }\n}\n",[456,615,616,621,626,630,635,640],{"__ignoreMap":454},[459,617,618],{"class":461,"line":462},[459,619,620],{},"\u002F\u002F T phải là U hoặc subtype của U\n",[459,622,623],{"class":461,"line":468},[459,624,625],{},"public class Container\u003CT, U> where T : U { }\n",[459,627,628],{"class":461,"line":474},[459,629,478],{"emptyLinePlaceholder":477},[459,631,632],{"class":461,"line":481},[459,633,634],{},"public class Notifier\u003CT> where T : Animal {\n",[459,636,637],{"class":461,"line":487},[459,638,639],{},"    public void Notify\u003CU>(U pet) where U : T { ... }\n",[459,641,642],{"class":461,"line":493},[459,643,535],{},[436,645,647],{"id":646},"constraint-typescript","Constraint TypeScript",[449,649,653],{"className":650,"code":651,"language":652,"meta":454,"style":454},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F T có property length\nfunction longest\u003CT extends { length: number }>(a: T, b: T): T {\n    return a.length >= b.length ? a : b;\n}\n\n\u002F\u002F T là subtype của Animal\nfunction feed\u003CT extends Animal>(a: T) { a.eat(); }\n\n\u002F\u002F keyof constraint — pattern PV hot\nfunction get\u003CT, K extends keyof T>(obj: T, key: K): T[K] {\n    return obj[key];\n}\n\nconst user = { id: 1, name: \"Alice\" };\nget(user, \"name\");      \u002F\u002F string\nget(user, \"age\");       \u002F\u002F ❌ \"age\" không phải key\n\n\u002F\u002F Default + constraint\ninterface Config\u003CT extends object = {}> {\n    data: T;\n}\n","typescript",[456,654,655,661,725,763,767,771,776,822,826,831,888,906,911,916,959,984,1007,1012,1018,1044,1056],{"__ignoreMap":454},[459,656,657],{"class":461,"line":462},[459,658,660],{"class":659},"sHwdD","\u002F\u002F T có property length\n",[459,662,663,667,671,675,679,682,685,689,692,695,698,702,704,707,710,713,715,717,720,722],{"class":461,"line":468},[459,664,666],{"class":665},"spNyl","function",[459,668,670],{"class":669},"s2Zo4"," longest",[459,672,674],{"class":673},"sMK4o","\u003C",[459,676,678],{"class":677},"sBMFI","T",[459,680,681],{"class":665}," extends",[459,683,684],{"class":673}," {",[459,686,688],{"class":687},"swJcz"," length",[459,690,691],{"class":673},":",[459,693,694],{"class":677}," number",[459,696,697],{"class":673}," }>(",[459,699,701],{"class":700},"sHdIc","a",[459,703,691],{"class":673},[459,705,706],{"class":677}," T",[459,708,709],{"class":673},",",[459,711,712],{"class":700}," b",[459,714,691],{"class":673},[459,716,706],{"class":677},[459,718,719],{"class":673},"):",[459,721,706],{"class":677},[459,723,724],{"class":673}," {\n",[459,726,727,731,735,738,741,744,746,748,750,753,755,758,760],{"class":461,"line":474},[459,728,730],{"class":729},"s7zQu","    return",[459,732,734],{"class":733},"sTEyZ"," a",[459,736,737],{"class":673},".",[459,739,740],{"class":733},"length",[459,742,743],{"class":673}," >=",[459,745,712],{"class":733},[459,747,737],{"class":673},[459,749,740],{"class":733},[459,751,752],{"class":673}," ?",[459,754,734],{"class":733},[459,756,757],{"class":673}," :",[459,759,712],{"class":733},[459,761,762],{"class":673},";\n",[459,764,765],{"class":461,"line":481},[459,766,535],{"class":673},[459,768,769],{"class":461,"line":487},[459,770,478],{"emptyLinePlaceholder":477},[459,772,773],{"class":461,"line":493},[459,774,775],{"class":659},"\u002F\u002F T là subtype của Animal\n",[459,777,778,780,783,785,787,789,792,795,797,799,801,804,806,808,810,813,816,819],{"class":461,"line":498},[459,779,666],{"class":665},[459,781,782],{"class":669}," feed",[459,784,674],{"class":673},[459,786,678],{"class":677},[459,788,681],{"class":665},[459,790,791],{"class":677}," Animal",[459,793,794],{"class":673},">(",[459,796,701],{"class":700},[459,798,691],{"class":673},[459,800,706],{"class":677},[459,802,803],{"class":673},")",[459,805,684],{"class":673},[459,807,734],{"class":733},[459,809,737],{"class":673},[459,811,812],{"class":669},"eat",[459,814,815],{"class":687},"()",[459,817,818],{"class":673},";",[459,820,821],{"class":673}," }\n",[459,823,824],{"class":461,"line":504},[459,825,478],{"emptyLinePlaceholder":477},[459,827,828],{"class":461,"line":598},[459,829,830],{"class":659},"\u002F\u002F keyof constraint — pattern PV hot\n",[459,832,833,835,838,840,842,844,847,849,852,854,856,859,861,863,865,868,870,872,874,876,879,882,885],{"class":461,"line":604},[459,834,666],{"class":665},[459,836,837],{"class":669}," get",[459,839,674],{"class":673},[459,841,678],{"class":677},[459,843,709],{"class":673},[459,845,846],{"class":677}," K",[459,848,681],{"class":665},[459,850,851],{"class":673}," keyof",[459,853,706],{"class":677},[459,855,794],{"class":673},[459,857,858],{"class":700},"obj",[459,860,691],{"class":673},[459,862,706],{"class":677},[459,864,709],{"class":673},[459,866,867],{"class":700}," key",[459,869,691],{"class":673},[459,871,846],{"class":677},[459,873,719],{"class":673},[459,875,706],{"class":677},[459,877,878],{"class":733},"[",[459,880,881],{"class":677},"K",[459,883,884],{"class":733},"] ",[459,886,887],{"class":673},"{\n",[459,889,891,893,896,898,901,904],{"class":461,"line":890},11,[459,892,730],{"class":729},[459,894,895],{"class":733}," obj",[459,897,878],{"class":687},[459,899,900],{"class":733},"key",[459,902,903],{"class":687},"]",[459,905,762],{"class":673},[459,907,909],{"class":461,"line":908},12,[459,910,535],{"class":673},[459,912,914],{"class":461,"line":913},13,[459,915,478],{"emptyLinePlaceholder":477},[459,917,919,922,925,928,930,933,935,939,941,944,946,949,953,956],{"class":461,"line":918},14,[459,920,921],{"class":665},"const",[459,923,924],{"class":733}," user ",[459,926,927],{"class":673},"=",[459,929,684],{"class":673},[459,931,932],{"class":687}," id",[459,934,691],{"class":673},[459,936,938],{"class":937},"sbssI"," 1",[459,940,709],{"class":673},[459,942,943],{"class":687}," name",[459,945,691],{"class":673},[459,947,948],{"class":673}," \"",[459,950,952],{"class":951},"sfazB","Alice",[459,954,955],{"class":673},"\"",[459,957,958],{"class":673}," };\n",[459,960,962,965,968,970,972,975,977,979,981],{"class":461,"line":961},15,[459,963,964],{"class":669},"get",[459,966,967],{"class":733},"(user",[459,969,709],{"class":673},[459,971,948],{"class":673},[459,973,974],{"class":951},"name",[459,976,955],{"class":673},[459,978,803],{"class":733},[459,980,818],{"class":673},[459,982,983],{"class":659},"      \u002F\u002F string\n",[459,985,987,989,991,993,995,998,1000,1002,1004],{"class":461,"line":986},16,[459,988,964],{"class":669},[459,990,967],{"class":733},[459,992,709],{"class":673},[459,994,948],{"class":673},[459,996,997],{"class":951},"age",[459,999,955],{"class":673},[459,1001,803],{"class":733},[459,1003,818],{"class":673},[459,1005,1006],{"class":659},"       \u002F\u002F ❌ \"age\" không phải key\n",[459,1008,1010],{"class":461,"line":1009},17,[459,1011,478],{"emptyLinePlaceholder":477},[459,1013,1015],{"class":461,"line":1014},18,[459,1016,1017],{"class":659},"\u002F\u002F Default + constraint\n",[459,1019,1021,1024,1027,1029,1031,1033,1036,1039,1042],{"class":461,"line":1020},19,[459,1022,1023],{"class":665},"interface",[459,1025,1026],{"class":677}," Config",[459,1028,674],{"class":673},[459,1030,678],{"class":677},[459,1032,681],{"class":665},[459,1034,1035],{"class":677}," object",[459,1037,1038],{"class":673}," =",[459,1040,1041],{"class":673}," {}>",[459,1043,724],{"class":673},[459,1045,1047,1050,1052,1054],{"class":461,"line":1046},20,[459,1048,1049],{"class":687},"    data",[459,1051,691],{"class":673},[459,1053,706],{"class":677},[459,1055,762],{"class":673},[459,1057,1059],{"class":461,"line":1058},21,[459,1060,535],{"class":673},[1062,1063,1066,1085,1119],"callout",{"color":1064,"icon":1065},"warning","i-lucide-star",[432,1067,1068,1069,1073,1074],{},"⭐ ",[1070,1071,1072],"strong",{},"Câu PV cốt lõi:"," ",[1075,1076,955,1077,1080,1081,1084],"em",{},[456,1078,1079],{},"keyof T"," là gì và ",[456,1082,1083],{},"T[K]"," là gì?\"",[1086,1087,1088,1104],"ul",{},[1089,1090,1091,1093,1094,1097,1098,1093,1101,737],"li",{},[456,1092,1079],{}," = ",[1070,1095,1096],{},"union các key"," của T dưới dạng string literal type. ",[456,1099,1100],{},"keyof User",[456,1102,1103],{},"\"id\" | \"name\"",[1089,1105,1106,1108,1109,1112,1113,1093,1116,737],{},[456,1107,1083],{}," (indexed access) = ",[1070,1110,1111],{},"type của value"," ứng với key K. ",[456,1114,1115],{},"User[\"name\"]",[456,1117,1118],{},"string",[432,1120,1121],{},"Kết hợp lại = type-safe property access tổng quát.",[427,1123,1125],{"id":1124},"_2-pattern-hay-gặp-với-constraint","2. Pattern hay gặp với constraint",[436,1127,1129],{"id":1128},"pattern-1-repository-generic","Pattern 1 — Repository generic",[449,1131,1133],{"className":451,"code":1132,"language":453,"meta":454,"style":454},"public interface IEntity {\n    int Id { get; set; }\n}\n\npublic abstract class Repository\u003CT> where T : class, IEntity, new() {\n    protected readonly DbContext _ctx;\n    public Repository(DbContext ctx) => _ctx = ctx;\n    \n    public Task\u003CT?> GetByIdAsync(int id) =>\n        _ctx.Set\u003CT>().FindAsync(id).AsTask();\n    \n    public async Task AddAsync(T entity) {\n        _ctx.Set\u003CT>().Add(entity);\n        await _ctx.SaveChangesAsync();\n    }\n}\n",[456,1134,1135,1140,1145,1149,1153,1158,1163,1168,1173,1178,1183,1187,1192,1197,1202,1207],{"__ignoreMap":454},[459,1136,1137],{"class":461,"line":462},[459,1138,1139],{},"public interface IEntity {\n",[459,1141,1142],{"class":461,"line":468},[459,1143,1144],{},"    int Id { get; set; }\n",[459,1146,1147],{"class":461,"line":474},[459,1148,535],{},[459,1150,1151],{"class":461,"line":481},[459,1152,478],{"emptyLinePlaceholder":477},[459,1154,1155],{"class":461,"line":487},[459,1156,1157],{},"public abstract class Repository\u003CT> where T : class, IEntity, new() {\n",[459,1159,1160],{"class":461,"line":493},[459,1161,1162],{},"    protected readonly DbContext _ctx;\n",[459,1164,1165],{"class":461,"line":498},[459,1166,1167],{},"    public Repository(DbContext ctx) => _ctx = ctx;\n",[459,1169,1170],{"class":461,"line":504},[459,1171,1172],{},"    \n",[459,1174,1175],{"class":461,"line":598},[459,1176,1177],{},"    public Task\u003CT?> GetByIdAsync(int id) =>\n",[459,1179,1180],{"class":461,"line":604},[459,1181,1182],{},"        _ctx.Set\u003CT>().FindAsync(id).AsTask();\n",[459,1184,1185],{"class":461,"line":890},[459,1186,1172],{},[459,1188,1189],{"class":461,"line":908},[459,1190,1191],{},"    public async Task AddAsync(T entity) {\n",[459,1193,1194],{"class":461,"line":913},[459,1195,1196],{},"        _ctx.Set\u003CT>().Add(entity);\n",[459,1198,1199],{"class":461,"line":918},[459,1200,1201],{},"        await _ctx.SaveChangesAsync();\n",[459,1203,1204],{"class":461,"line":961},[459,1205,1206],{},"    }\n",[459,1208,1209],{"class":461,"line":986},[459,1210,535],{},[436,1212,1214],{"id":1213},"pattern-2-type-safe-builder","Pattern 2 — Type-safe builder",[449,1216,1218],{"className":650,"code":1217,"language":652,"meta":454,"style":454},"class QueryBuilder\u003CT = {}> {\n    constructor(private state: T = {} as T) {}\n    \n    where\u003CK extends string, V>(key: K, value: V): QueryBuilder\u003CT & Record\u003CK, V>> {\n        return new QueryBuilder({ ...this.state, [key]: value } as T & Record\u003CK, V>);\n    }\n    \n    build(): T { return this.state; }\n}\n\nconst q = new QueryBuilder()\n    .where(\"name\", \"Alice\")\n    .where(\"age\", 25)\n    .build();\n\u002F\u002F q: { name: string; age: number }\n",[456,1219,1220,1238,1271,1275,1338,1398,1402,1406,1430,1434,1438,1454,1481,1502,1513],{"__ignoreMap":454},[459,1221,1222,1225,1228,1230,1232,1234,1236],{"class":461,"line":462},[459,1223,1224],{"class":665},"class",[459,1226,1227],{"class":677}," QueryBuilder",[459,1229,674],{"class":673},[459,1231,678],{"class":677},[459,1233,1038],{"class":673},[459,1235,1041],{"class":673},[459,1237,724],{"class":673},[459,1239,1240,1243,1246,1249,1252,1254,1256,1258,1261,1264,1266,1268],{"class":461,"line":468},[459,1241,1242],{"class":665},"    constructor",[459,1244,1245],{"class":673},"(",[459,1247,1248],{"class":665},"private",[459,1250,1251],{"class":700}," state",[459,1253,691],{"class":673},[459,1255,706],{"class":677},[459,1257,1038],{"class":673},[459,1259,1260],{"class":673}," {}",[459,1262,1263],{"class":729}," as",[459,1265,706],{"class":677},[459,1267,803],{"class":673},[459,1269,1270],{"class":673}," {}\n",[459,1272,1273],{"class":461,"line":474},[459,1274,1172],{"class":733},[459,1276,1277,1280,1282,1284,1286,1289,1291,1294,1296,1298,1300,1302,1304,1307,1309,1311,1313,1315,1317,1319,1322,1325,1327,1329,1331,1333,1336],{"class":461,"line":481},[459,1278,1279],{"class":687},"    where",[459,1281,674],{"class":673},[459,1283,881],{"class":677},[459,1285,681],{"class":665},[459,1287,1288],{"class":677}," string",[459,1290,709],{"class":673},[459,1292,1293],{"class":677}," V",[459,1295,794],{"class":673},[459,1297,900],{"class":700},[459,1299,691],{"class":673},[459,1301,846],{"class":677},[459,1303,709],{"class":673},[459,1305,1306],{"class":700}," value",[459,1308,691],{"class":673},[459,1310,1293],{"class":677},[459,1312,719],{"class":673},[459,1314,1227],{"class":677},[459,1316,674],{"class":673},[459,1318,678],{"class":677},[459,1320,1321],{"class":673}," &",[459,1323,1324],{"class":677}," Record",[459,1326,674],{"class":673},[459,1328,881],{"class":677},[459,1330,709],{"class":673},[459,1332,1293],{"class":677},[459,1334,1335],{"class":673},">>",[459,1337,724],{"class":673},[459,1339,1340,1343,1346,1348,1350,1353,1356,1359,1361,1364,1366,1368,1370,1372,1375,1377,1379,1381,1383,1385,1387,1389,1391,1394,1396],{"class":461,"line":487},[459,1341,1342],{"class":729},"        return",[459,1344,1345],{"class":673}," new",[459,1347,1227],{"class":669},[459,1349,1245],{"class":687},[459,1351,1352],{"class":673},"{",[459,1354,1355],{"class":673}," ...this.",[459,1357,1358],{"class":733},"state",[459,1360,709],{"class":673},[459,1362,1363],{"class":687}," [",[459,1365,900],{"class":733},[459,1367,903],{"class":687},[459,1369,691],{"class":673},[459,1371,1306],{"class":733},[459,1373,1374],{"class":673}," }",[459,1376,1263],{"class":729},[459,1378,706],{"class":677},[459,1380,1321],{"class":673},[459,1382,1324],{"class":677},[459,1384,674],{"class":673},[459,1386,881],{"class":677},[459,1388,709],{"class":673},[459,1390,1293],{"class":677},[459,1392,1393],{"class":673},">",[459,1395,803],{"class":687},[459,1397,762],{"class":673},[459,1399,1400],{"class":461,"line":493},[459,1401,1206],{"class":673},[459,1403,1404],{"class":461,"line":498},[459,1405,1172],{"class":733},[459,1407,1408,1411,1414,1416,1418,1421,1424,1426,1428],{"class":461,"line":504},[459,1409,1410],{"class":687},"    build",[459,1412,1413],{"class":673},"():",[459,1415,706],{"class":677},[459,1417,684],{"class":673},[459,1419,1420],{"class":729}," return",[459,1422,1423],{"class":673}," this.",[459,1425,1358],{"class":733},[459,1427,818],{"class":673},[459,1429,821],{"class":673},[459,1431,1432],{"class":461,"line":598},[459,1433,535],{"class":673},[459,1435,1436],{"class":461,"line":604},[459,1437,478],{"emptyLinePlaceholder":477},[459,1439,1440,1442,1445,1447,1449,1451],{"class":461,"line":890},[459,1441,921],{"class":665},[459,1443,1444],{"class":733}," q ",[459,1446,927],{"class":673},[459,1448,1345],{"class":673},[459,1450,1227],{"class":669},[459,1452,1453],{"class":733},"()\n",[459,1455,1456,1459,1462,1464,1466,1468,1470,1472,1474,1476,1478],{"class":461,"line":908},[459,1457,1458],{"class":673},"    .",[459,1460,1461],{"class":669},"where",[459,1463,1245],{"class":733},[459,1465,955],{"class":673},[459,1467,974],{"class":951},[459,1469,955],{"class":673},[459,1471,709],{"class":673},[459,1473,948],{"class":673},[459,1475,952],{"class":951},[459,1477,955],{"class":673},[459,1479,1480],{"class":733},")\n",[459,1482,1483,1485,1487,1489,1491,1493,1495,1497,1500],{"class":461,"line":913},[459,1484,1458],{"class":673},[459,1486,1461],{"class":669},[459,1488,1245],{"class":733},[459,1490,955],{"class":673},[459,1492,997],{"class":951},[459,1494,955],{"class":673},[459,1496,709],{"class":673},[459,1498,1499],{"class":937}," 25",[459,1501,1480],{"class":733},[459,1503,1504,1506,1509,1511],{"class":461,"line":918},[459,1505,1458],{"class":673},[459,1507,1508],{"class":669},"build",[459,1510,815],{"class":733},[459,1512,762],{"class":673},[459,1514,1515],{"class":461,"line":961},[459,1516,1517],{"class":659},"\u002F\u002F q: { name: string; age: number }\n",[436,1519,1521],{"id":1520},"pattern-3-constraint-default-factory","Pattern 3 — Constraint + default + factory",[449,1523,1525],{"className":451,"code":1524,"language":453,"meta":454,"style":454},"public class Factory\u003CT> where T : new() {\n    public T Create() => new T();\n    public List\u003CT> CreateMany(int n) => Enumerable.Range(0, n).Select(_ => new T()).ToList();\n}\n",[456,1526,1527,1531,1535,1540],{"__ignoreMap":454},[459,1528,1529],{"class":461,"line":462},[459,1530,525],{},[459,1532,1533],{"class":461,"line":468},[459,1534,530],{},[459,1536,1537],{"class":461,"line":474},[459,1538,1539],{},"    public List\u003CT> CreateMany(int n) => Enumerable.Range(0, n).Select(_ => new T()).ToList();\n",[459,1541,1542],{"class":461,"line":481},[459,1543,535],{},[427,1545,1547],{"id":1546},"_3-variance-bài-học-sâu","3. Variance — bài học sâu",[1549,1550,1551],"blockquote",{},[432,1552,1553,1556,1557,1560,1561,1564],{},[1070,1554,1555],{},"Variance",": nếu ",[456,1558,1559],{},"Dog : Animal",", vậy ",[456,1562,1563],{},"List\u003CDog> : List\u003CAnimal>"," không?",[432,1566,1567],{},"3 khả năng:",[1569,1570,1571,1588,1599],"field-group",{},[1572,1573,1576,1577],"field",{"name":1574,"type":1575},"Covariant","out","Nếu Dog : Animal thì F",[1578,1579,1580,1581],"dog",{}," : F",[1582,1583,1584,1585],"animal",{},". ",[1070,1586,1587],{},"Subtyping được giữ.",[1572,1589,1576,1592],{"name":1590,"type":1591},"Contravariant","in",[1582,1593,1580,1594],{},[1578,1595,1584,1596],{},[1070,1597,1598],{},"Đảo chiều.",[1572,1600,1603,1604],{"name":1601,"type":1602},"Invariant","(default)","F",[1578,1605,1606,1607],{}," và F",[1582,1608,1609],{}," không có quan hệ subtype.",[436,1611,1613],{"id":1612},"vì-sao-quan-trọng","Vì sao quan trọng?",[449,1615,1617],{"className":451,"code":1616,"language":453,"meta":454,"style":454},"\u002F\u002F Liệu code này safe?\nList\u003CDog> dogs = new() { new Dog(\"Rex\") };\nList\u003CAnimal> animals = dogs;        \u002F\u002F covariant?\nanimals.Add(new Cat(\"Tom\"));        \u002F\u002F ⚠️ Cat vào list of Dog!\nDog d = dogs[1];                    \u002F\u002F CRASH\n",[456,1618,1619,1624,1629,1634,1639],{"__ignoreMap":454},[459,1620,1621],{"class":461,"line":462},[459,1622,1623],{},"\u002F\u002F Liệu code này safe?\n",[459,1625,1626],{"class":461,"line":468},[459,1627,1628],{},"List\u003CDog> dogs = new() { new Dog(\"Rex\") };\n",[459,1630,1631],{"class":461,"line":474},[459,1632,1633],{},"List\u003CAnimal> animals = dogs;        \u002F\u002F covariant?\n",[459,1635,1636],{"class":461,"line":481},[459,1637,1638],{},"animals.Add(new Cat(\"Tom\"));        \u002F\u002F ⚠️ Cat vào list of Dog!\n",[459,1640,1641],{"class":461,"line":487},[459,1642,1643],{},"Dog d = dogs[1];                    \u002F\u002F CRASH\n",[432,1645,1646,1647,1650,1651,1654,1655,1657],{},"→ ",[456,1648,1649],{},"List\u003CT>"," là ",[1070,1652,1653],{},"invariant"," (",[456,1656,678],{}," xuất hiện cả input và output) — đúng đắn.",[436,1659,1661,1662,1664],{"id":1660},"covariant-out-parameter","Covariant — ",[456,1663,1575],{}," parameter",[449,1666,1668],{"className":451,"code":1667,"language":453,"meta":454,"style":454},"\u002F\u002F IEnumerable\u003CT> là COVARIANT — T chỉ ở vị trí output (return)\npublic interface IEnumerable\u003Cout T> {\n    IEnumerator\u003CT> GetEnumerator();    \u002F\u002F T ở output\n}\n\nIEnumerable\u003CDog> dogs = new List\u003CDog>();\nIEnumerable\u003CAnimal> animals = dogs;     \u002F\u002F ✅ OK — chỉ đọc, không add Cat được\n",[456,1669,1670,1675,1680,1685,1689,1693,1698],{"__ignoreMap":454},[459,1671,1672],{"class":461,"line":462},[459,1673,1674],{},"\u002F\u002F IEnumerable\u003CT> là COVARIANT — T chỉ ở vị trí output (return)\n",[459,1676,1677],{"class":461,"line":468},[459,1678,1679],{},"public interface IEnumerable\u003Cout T> {\n",[459,1681,1682],{"class":461,"line":474},[459,1683,1684],{},"    IEnumerator\u003CT> GetEnumerator();    \u002F\u002F T ở output\n",[459,1686,1687],{"class":461,"line":481},[459,1688,535],{},[459,1690,1691],{"class":461,"line":487},[459,1692,478],{"emptyLinePlaceholder":477},[459,1694,1695],{"class":461,"line":493},[459,1696,1697],{},"IEnumerable\u003CDog> dogs = new List\u003CDog>();\n",[459,1699,1700],{"class":461,"line":498},[459,1701,1702],{},"IEnumerable\u003CAnimal> animals = dogs;     \u002F\u002F ✅ OK — chỉ đọc, không add Cat được\n",[436,1704,1706,1707,1664],{"id":1705},"contravariant-in-parameter","Contravariant — ",[456,1708,1591],{},[449,1710,1712],{"className":451,"code":1711,"language":453,"meta":454,"style":454},"\u002F\u002F IComparer\u003CT> là CONTRAVARIANT — T chỉ ở input\npublic interface IComparer\u003Cin T> {\n    int Compare(T x, T y);\n}\n\nIComparer\u003CAnimal> animalCmp = new AnimalAgeComparer();\nIComparer\u003CDog> dogCmp = animalCmp;      \u002F\u002F ✅ — so sánh được Dog vì so được Animal\n",[456,1713,1714,1719,1724,1729,1733,1737,1742],{"__ignoreMap":454},[459,1715,1716],{"class":461,"line":462},[459,1717,1718],{},"\u002F\u002F IComparer\u003CT> là CONTRAVARIANT — T chỉ ở input\n",[459,1720,1721],{"class":461,"line":468},[459,1722,1723],{},"public interface IComparer\u003Cin T> {\n",[459,1725,1726],{"class":461,"line":474},[459,1727,1728],{},"    int Compare(T x, T y);\n",[459,1730,1731],{"class":461,"line":481},[459,1732,535],{},[459,1734,1735],{"class":461,"line":487},[459,1736,478],{"emptyLinePlaceholder":477},[459,1738,1739],{"class":461,"line":493},[459,1740,1741],{},"IComparer\u003CAnimal> animalCmp = new AnimalAgeComparer();\n",[459,1743,1744],{"class":461,"line":498},[459,1745,1746],{},"IComparer\u003CDog> dogCmp = animalCmp;      \u002F\u002F ✅ — so sánh được Dog vì so được Animal\n",[1062,1748,1749,1755,1758],{"color":1064,"icon":1065},[432,1750,1068,1751,1754],{},[1070,1752,1753],{},"Mnemonic:"," \"out → covariant (cùng hướng), in → contravariant (ngược hướng)\".",[432,1756,1757],{},"Rule of thumb:",[1086,1759,1760,1766,1772],{},[1089,1761,1762,1765],{},[1070,1763,1764],{},"Producer"," (output) → covariant.",[1089,1767,1768,1771],{},[1070,1769,1770],{},"Consumer"," (input) → contravariant.",[1089,1773,1774,1777],{},[1070,1775,1776],{},"Mixed"," (cả input và output) → invariant.",[436,1779,1781],{"id":1780},"variance-trong-ts","Variance trong TS",[432,1783,1784,1785,1788],{},"TS variance ",[1070,1786,1787],{},"automatically inferred"," từ cách type parameter được dùng:",[449,1790,1792],{"className":650,"code":1791,"language":652,"meta":454,"style":454},"\u002F\u002F Covariant — T chỉ ở return\ninterface Producer\u003CT> {\n    produce(): T;\n}\n\ndeclare const dogProd: Producer\u003CDog>;\nconst animalProd: Producer\u003CAnimal> = dogProd;   \u002F\u002F ✅ covariant\n\n\u002F\u002F Contravariant — T chỉ ở input\ninterface Consumer\u003CT> {\n    consume(value: T): void;\n}\n\ndeclare const animalCon: Consumer\u003CAnimal>;\nconst dogCon: Consumer\u003CDog> = animalCon;        \u002F\u002F ✅ contravariant\n",[456,1793,1794,1799,1814,1825,1829,1833,1856,1883,1887,1892,1907,1928,1932,1936,1955],{"__ignoreMap":454},[459,1795,1796],{"class":461,"line":462},[459,1797,1798],{"class":659},"\u002F\u002F Covariant — T chỉ ở return\n",[459,1800,1801,1803,1806,1808,1810,1812],{"class":461,"line":468},[459,1802,1023],{"class":665},[459,1804,1805],{"class":677}," Producer",[459,1807,674],{"class":673},[459,1809,678],{"class":677},[459,1811,1393],{"class":673},[459,1813,724],{"class":673},[459,1815,1816,1819,1821,1823],{"class":461,"line":474},[459,1817,1818],{"class":687},"    produce",[459,1820,1413],{"class":673},[459,1822,706],{"class":677},[459,1824,762],{"class":673},[459,1826,1827],{"class":461,"line":481},[459,1828,535],{"class":673},[459,1830,1831],{"class":461,"line":487},[459,1832,478],{"emptyLinePlaceholder":477},[459,1834,1835,1838,1841,1844,1846,1848,1850,1853],{"class":461,"line":493},[459,1836,1837],{"class":665},"declare",[459,1839,1840],{"class":665}," const",[459,1842,1843],{"class":733}," dogProd",[459,1845,691],{"class":673},[459,1847,1805],{"class":677},[459,1849,674],{"class":673},[459,1851,1852],{"class":677},"Dog",[459,1854,1855],{"class":673},">;\n",[459,1857,1858,1860,1863,1865,1867,1869,1872,1874,1876,1878,1880],{"class":461,"line":498},[459,1859,921],{"class":665},[459,1861,1862],{"class":733}," animalProd",[459,1864,691],{"class":673},[459,1866,1805],{"class":677},[459,1868,674],{"class":673},[459,1870,1871],{"class":677},"Animal",[459,1873,1393],{"class":673},[459,1875,1038],{"class":673},[459,1877,1843],{"class":733},[459,1879,818],{"class":673},[459,1881,1882],{"class":659},"   \u002F\u002F ✅ covariant\n",[459,1884,1885],{"class":461,"line":504},[459,1886,478],{"emptyLinePlaceholder":477},[459,1888,1889],{"class":461,"line":598},[459,1890,1891],{"class":659},"\u002F\u002F Contravariant — T chỉ ở input\n",[459,1893,1894,1896,1899,1901,1903,1905],{"class":461,"line":604},[459,1895,1023],{"class":665},[459,1897,1898],{"class":677}," Consumer",[459,1900,674],{"class":673},[459,1902,678],{"class":677},[459,1904,1393],{"class":673},[459,1906,724],{"class":673},[459,1908,1909,1912,1914,1917,1919,1921,1923,1926],{"class":461,"line":890},[459,1910,1911],{"class":687},"    consume",[459,1913,1245],{"class":673},[459,1915,1916],{"class":700},"value",[459,1918,691],{"class":673},[459,1920,706],{"class":677},[459,1922,719],{"class":673},[459,1924,1925],{"class":677}," void",[459,1927,762],{"class":673},[459,1929,1930],{"class":461,"line":908},[459,1931,535],{"class":673},[459,1933,1934],{"class":461,"line":913},[459,1935,478],{"emptyLinePlaceholder":477},[459,1937,1938,1940,1942,1945,1947,1949,1951,1953],{"class":461,"line":918},[459,1939,1837],{"class":665},[459,1941,1840],{"class":665},[459,1943,1944],{"class":733}," animalCon",[459,1946,691],{"class":673},[459,1948,1898],{"class":677},[459,1950,674],{"class":673},[459,1952,1871],{"class":677},[459,1954,1855],{"class":673},[459,1956,1957,1959,1962,1964,1966,1968,1970,1972,1974,1976,1978],{"class":461,"line":961},[459,1958,921],{"class":665},[459,1960,1961],{"class":733}," dogCon",[459,1963,691],{"class":673},[459,1965,1898],{"class":677},[459,1967,674],{"class":673},[459,1969,1852],{"class":677},[459,1971,1393],{"class":673},[459,1973,1038],{"class":673},[459,1975,1944],{"class":733},[459,1977,818],{"class":673},[459,1979,1980],{"class":659},"        \u002F\u002F ✅ contravariant\n",[432,1982,1983,1984,1654,1987,1989,1990,719],{},"TypeScript 4.7+ thêm ",[1070,1985,1986],{},"explicit variance annotation",[456,1988,1591],{},", ",[456,1991,1575],{},[449,1993,1995],{"className":650,"code":1994,"language":652,"meta":454,"style":454},"interface Producer\u003Cout T> { produce(): T; }\ninterface Consumer\u003Cin T> { consume(x: T): void; }\ninterface Pair\u003Cin out T> { value: T; setValue(x: T): void; }   \u002F\u002F invariant\n",[456,1996,1997,2024,2060],{"__ignoreMap":454},[459,1998,1999,2001,2003,2005,2007,2009,2011,2013,2016,2018,2020,2022],{"class":461,"line":462},[459,2000,1023],{"class":665},[459,2002,1805],{"class":677},[459,2004,674],{"class":673},[459,2006,1575],{"class":665},[459,2008,706],{"class":677},[459,2010,1393],{"class":673},[459,2012,684],{"class":673},[459,2014,2015],{"class":687}," produce",[459,2017,1413],{"class":673},[459,2019,706],{"class":677},[459,2021,818],{"class":673},[459,2023,821],{"class":673},[459,2025,2026,2028,2030,2032,2034,2036,2038,2040,2043,2045,2048,2050,2052,2054,2056,2058],{"class":461,"line":468},[459,2027,1023],{"class":665},[459,2029,1898],{"class":677},[459,2031,674],{"class":673},[459,2033,1591],{"class":665},[459,2035,706],{"class":677},[459,2037,1393],{"class":673},[459,2039,684],{"class":673},[459,2041,2042],{"class":687}," consume",[459,2044,1245],{"class":673},[459,2046,2047],{"class":700},"x",[459,2049,691],{"class":673},[459,2051,706],{"class":677},[459,2053,719],{"class":673},[459,2055,1925],{"class":677},[459,2057,818],{"class":673},[459,2059,821],{"class":673},[459,2061,2062,2064,2067,2069,2071,2074,2076,2078,2080,2082,2084,2086,2088,2091,2093,2095,2097,2099,2101,2103,2105,2107],{"class":461,"line":474},[459,2063,1023],{"class":665},[459,2065,2066],{"class":677}," Pair",[459,2068,674],{"class":673},[459,2070,1591],{"class":665},[459,2072,2073],{"class":665}," out",[459,2075,706],{"class":677},[459,2077,1393],{"class":673},[459,2079,684],{"class":673},[459,2081,1306],{"class":687},[459,2083,691],{"class":673},[459,2085,706],{"class":677},[459,2087,818],{"class":673},[459,2089,2090],{"class":687}," setValue",[459,2092,1245],{"class":673},[459,2094,2047],{"class":700},[459,2096,691],{"class":673},[459,2098,706],{"class":677},[459,2100,719],{"class":673},[459,2102,1925],{"class":677},[459,2104,818],{"class":673},[459,2106,1374],{"class":673},[459,2108,2109],{"class":659},"   \u002F\u002F invariant\n",[1062,2111,2114,2120],{"color":2112,"icon":2113},"primary","i-lucide-info",[432,2115,2116,2119],{},[1070,2117,2118],{},"Function type variance"," đặc biệt — return covariant, parameter contravariant:",[449,2121,2123],{"className":650,"code":2122,"language":652,"meta":454,"style":454},"type Fn1 = (a: Animal) => Dog;\ntype Fn2 = (a: Dog) => Animal;\n\u002F\u002F Fn1 IS-A Fn2?\n\u002F\u002F   - Return Dog : Animal ✅ (covariant return)\n\u002F\u002F   - Param Animal : Dog? — đảo chiều ✅ (contravariant param)\n\u002F\u002F → YES, Fn1 assignable to Fn2.\n",[456,2124,2125,2153,2178,2183,2188,2193],{"__ignoreMap":454},[459,2126,2127,2130,2133,2135,2137,2139,2141,2143,2145,2148,2151],{"class":461,"line":462},[459,2128,2129],{"class":665},"type",[459,2131,2132],{"class":677}," Fn1",[459,2134,1038],{"class":673},[459,2136,1654],{"class":673},[459,2138,701],{"class":700},[459,2140,691],{"class":673},[459,2142,791],{"class":677},[459,2144,803],{"class":673},[459,2146,2147],{"class":665}," =>",[459,2149,2150],{"class":677}," Dog",[459,2152,762],{"class":673},[459,2154,2155,2157,2160,2162,2164,2166,2168,2170,2172,2174,2176],{"class":461,"line":468},[459,2156,2129],{"class":665},[459,2158,2159],{"class":677}," Fn2",[459,2161,1038],{"class":673},[459,2163,1654],{"class":673},[459,2165,701],{"class":700},[459,2167,691],{"class":673},[459,2169,2150],{"class":677},[459,2171,803],{"class":673},[459,2173,2147],{"class":665},[459,2175,791],{"class":677},[459,2177,762],{"class":673},[459,2179,2180],{"class":461,"line":474},[459,2181,2182],{"class":659},"\u002F\u002F Fn1 IS-A Fn2?\n",[459,2184,2185],{"class":461,"line":481},[459,2186,2187],{"class":659},"\u002F\u002F   - Return Dog : Animal ✅ (covariant return)\n",[459,2189,2190],{"class":461,"line":487},[459,2191,2192],{"class":659},"\u002F\u002F   - Param Animal : Dog? — đảo chiều ✅ (contravariant param)\n",[459,2194,2195],{"class":461,"line":493},[459,2196,2197],{"class":659},"\u002F\u002F → YES, Fn1 assignable to Fn2.\n",[427,2199,2201],{"id":2200},"_4-bivariant-function-parameter-ts-quirk","4. Bivariant function parameter — TS quirk",[432,2203,2204,2205,2208],{},"TS mặc định ",[1070,2206,2207],{},"bivariant function parameter"," (vừa covariant vừa contravariant). Không strict theo lý thuyết. Có thể bật strict:",[449,2210,2214],{"className":2211,"code":2212,"language":2213,"meta":454,"style":454},"language-jsonc shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{ \"compilerOptions\": { \"strictFunctionTypes\": true } }\n","jsonc",[456,2215,2216],{"__ignoreMap":454},[459,2217,2218],{"class":461,"line":462},[459,2219,2212],{},[432,2221,2222],{},"Với strict, function param chỉ contravariant. Hợp lý hơn nhưng có thể phá code cũ.",[427,2224,2226],{"id":2225},"_5-variance-khi-nào-quan-trọng","5. Variance khi nào quan trọng?",[1062,2228,2229,2242],{"color":2112,"icon":1065},[432,2230,2231,2232],{},"⭐ Câu PV junior+: ",[1075,2233,2234,2235,2238,2239,2241],{},"\"Tại sao ",[456,2236,2237],{},"IEnumerable\u003CT>"," covariant mà ",[456,2240,1649],{}," không?\"",[1549,2243,2244],{},[432,2245,955,2246,2248,2249,2251,2252,2255,2256,2259,2260,2263,2264,2267,2268,2270],{},[456,2247,2237],{}," chỉ có method trả T (output) → safe để covariant. ",[456,2250,1649],{}," có cả ",[456,2253,2254],{},"Add(T)"," (input) và ",[456,2257,2258],{},"this[int]"," (output) → mixed → invariant. Nếu covariant, có thể Add ",[456,2261,2262],{},"Cat"," vào ",[456,2265,2266],{},"List\u003CAnimal>"," chứa ",[456,2269,1852],{}," → crash.\"",[432,2272,2273,2274,2276,2277,2279],{},"Practical use: design API library — thiết kế interface có ",[456,2275,1591],{},"\u002F",[456,2278,1575],{}," đúng → caller dùng linh hoạt hơn.",[1062,2281,2283,2284],{"color":2112,"icon":2282},"i-lucide-arrow-right","Tiếp theo: ",[701,2285,2286],{"href":351},"C# vs TypeScript — Reified vs Erased",[2288,2289,2290],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}",{"title":454,"searchDepth":468,"depth":468,"links":2292},[2293,2297,2302,2310,2311],{"id":429,"depth":468,"text":430,"children":2294},[2295,2296],{"id":438,"depth":474,"text":439},{"id":646,"depth":474,"text":647},{"id":1124,"depth":468,"text":1125,"children":2298},[2299,2300,2301],{"id":1128,"depth":474,"text":1129},{"id":1213,"depth":474,"text":1214},{"id":1520,"depth":474,"text":1521},{"id":1546,"depth":468,"text":1547,"children":2303},[2304,2305,2307,2309],{"id":1612,"depth":474,"text":1613},{"id":1660,"depth":474,"text":2306},"Covariant — out parameter",{"id":1705,"depth":474,"text":2308},"Contravariant — in parameter",{"id":1780,"depth":474,"text":1781},{"id":2200,"depth":468,"text":2201},{"id":2225,"depth":468,"text":2226},"Constraint (where \u002F extends), covariance, contravariance, invariance — hiểu đúng để dùng đúng.","md",null,{},{"title":345,"icon":348},{"title":422,"description":2312},"PijOQDOX7mnZU5S2tIOGyskVyvFBab5jB1Gdq4ohRFM",[2320,2322],{"title":340,"path":341,"stem":342,"description":2321,"icon":343,"children":-1},"Generic function, class, interface, method — cú pháp C# và TypeScript song song.",{"title":350,"path":351,"stem":352,"description":2323,"icon":353,"children":-1},"Khác biệt cốt lõi runtime — C# generic giữ type info, TypeScript xoá hết. Implication thực tế.",1783490359300]