Microsoft Roslyn so với CodeDom


110

Từ một thông cáo báo chí ngày hôm qua trên InfoWorld về Microsoft Roslyn mới :

Ưu điểm rõ ràng nhất của loại trình biên dịch "giải cấu trúc" này là nó cho phép toàn bộ quá trình biên dịch-thực thi được gọi từ bên trong các ứng dụng .Net. Hejlsberg đã trình diễn một chương trình C # chuyển một vài đoạn mã tới trình biên dịch C # dưới dạng chuỗi; trình biên dịch trả về mã hợp ngữ IL kết quả dưới dạng một đối tượng, sau đó được chuyển đến Thời gian chạy ngôn ngữ chung (CLR) để thực thi. Voilà! Với Roslyn, C # có được khả năng tạo và gọi mã của một ngôn ngữ động trong thời gian chạy.

Tôi đã có thể làm điều này kể từ khi phát hành .NET 4 CSharpCodeProvider.CompileAssemblyFromSourcemà trên thực tế tôi sử dụng trong một dự án ASP.Net được viết cách đây một thời gian thực hiện chính xác điều đó - cho phép người dùng nhập mã vào hộp văn bản, chọn hợp ngữ / không gian tên để tham chiếu, sau đó thực thi và hiển thị đầu ra từ mã đó một cách nhanh chóng để kiểm tra mã môi trường trực tiếp trên Windows Azure.

CodeDommột phần của / tiền thân của Roslyn? Lợi ích đặc biệt của Roslyn là CodeDomgì?

Câu trả lời:


240

Tuyên bố từ chối trách nhiệm : Tôi làm việc cho Microsoft trong nhóm Roslyn.

CodeDom là tiền thân của Roslyn, nhưng chỉ có liên quan nhỏ. Về cơ bản, CodeDom là một cách đơn giản và (phần nào) về ngôn ngữ để tạo mã đã được thêm vào .NET 1.0 để hỗ trợ các nhà thiết kế (gọi là WinForms). Bởi vì CodeDom là một nỗ lực cung cấp một mô hình thống nhất có thể tạo mã bằng C #, VB và các ngôn ngữ khác, nó thiếu độ trung thực cao với bất kỳ ngôn ngữ nào mà nó hỗ trợ (đó là lý do tại sao bạn không thể tạo một câu lệnh switch với CodeDom). CSharpCodeProvider.CompileAssemblyFromSource chỉ đơn giản là một trình bao bọc xung quanh việc thực thi csc.exe.

Roslyn là một con vật hoàn toàn khác. Nó là bản viết lại của cả trình biên dịch C # và VB từ đầu sử dụng mã được quản lý - C # trong C # và VB trong VB (các phiên bản csc.exe và vbc.exe xuất xưởng ngày nay được viết bằng mã gốc). Ưu điểm của việc xây dựng chúng trong mã được quản lý là người dùng có thể tham chiếu các trình biên dịch thực như các thư viện từ các ứng dụng .NET (không cần trình bao bọc).

Trong khi xây dựng từng thành phần của quy trình biên dịch, chúng tôi đã đưa ra các API công khai ở trên cùng:

  • Trình phân tích cú pháp -> API cây cú pháp
  • Bảng ký hiệu / Nhập siêu dữ liệu -> API ký hiệu
  • Binder -> API phân tích luồng và ràng buộc
  • IL Emitter -> API phát

Roslyn có thể được sử dụng như một trình tạo mã nguồn C # và VB phức tạp, nhưng đó là nơi kết thúc sự tương đồng với CodeDom. Các API của trình biên dịch Roslyn có thể được sử dụng để phân tích cú pháp mã, thực hiện phân tích ngữ nghĩa, biên dịch và đánh giá mã động, v.v.

Ngoài các trình biên dịch, nhóm Roslyn cũng đang xây dựng lại các tính năng Visual Studio C # và VB IDE trên đầu các API trình biên dịch công khai. Vì vậy, các API trình biên dịch đủ phong phú để xây dựng các công cụ thời gian thiết kế Visual Studio, như IntelliSense và tái cấu trúc Phương pháp trích xuất. Ngoài ra, ở các lớp phía trên trình biên dịch, Roslyn cung cấp các dịch vụ để phân tích cấp cao hơn hoặc chuyển đổi dữ liệu. Ví dụ: có các dịch vụ để định dạng mã bằng cách sử dụng quy tắc định dạng C # và VB hoặc tìm tất cả các tham chiếu đến một ký hiệu cụ thể trong một giải pháp.

Thực sự, không chỉ có một lợi ích đặc biệt của Roslyn so với CodeDom. Khi CodeDom đáp ứng nhu cầu tạo mã rất cụ thể, Roslyn đang giải quyết toàn bộ không gian công cụ ngôn ngữ bằng cách cung cấp một khuôn khổ cho phép bạn xây dựng bất kỳ loại công cụ ngôn ngữ C # hoặc VB nào mà bạn có thể nghĩ đến.


2
@Dustin: Roslyn sẽ hỗ trợ các ngôn ngữ khác chứ? JavaScript (.NET) chẳng hạn?
Diego Barros

@Dustin: Điều này hoàn hảo để xây dựng trải nghiệm IDE hoàn chỉnh có thể thực thi chất lượng mã trong tổ chức của tôi, mặc dù tôi không thấy sự thay thế hoàn toàn của việc xem xét mã thủ công nhưng tôi thấy chất lượng đã tăng lên đáng kể. Sớm!
Jerric Lyns John

Sẽ thật tuyệt nếu ai đó đã tạo một công cụ dựa trên Roslyn để chuyển đổi mã sử dụng CodeDom thành mã sử dụng SyntaxFactory của Roslyn ... (Một phần vì .Net Core có Roslyn nhưng không có CodeDom và tôi đang sử dụng một lib được xây dựng xung quanh CodeDom )
Emyr

43

CodeDom cho phép bạn biên dịch - nhưng nó không cung cấp cho bạn khả năng thực sự lấy thông tin về bản thân mã (ngoại trừ lỗi trình biên dịch). Về cơ bản, đó là một hộp đen nơi bạn nói "biên dịch cái này" và nó nói "Tôi đã thành công" hoặc "Tôi đã thất bại, đây là một số lỗi".

Roslyn cho phép bạn hoàn toàn kiểm tra và xây dựng mã một cách nhanh chóng. Điều này bao gồm những thứ như có thể xem / kiểm tra các nhận xét trong một đoạn mã nguồn, thông tin chi tiết về cấu trúc đầy đủ, v.v. Bạn có thể xem qua và lấy toàn bộ cây cú pháp của nguồn mà bạn chuyển vào Roslyn và thực hiện phân tích chi tiết hoặc các phép biến hình trên đó.

Với thông tin cú pháp phong phú, đầy đủ, bạn có rất nhiều quyền kiểm soát và tính linh hoạt. Đây là cách, ví dụ, mẫu hoạt động sao chép một khối mã C # và dán nó dưới dạng mã VB.NET. Với Roslyn, bạn có thể làm được nhiều việc hơn là chỉ biên dịch - bạn cũng có thể thao tác mã một cách rõ ràng. Điều này sẽ làm cho việc tạo công cụ đơn giản hơn rất nhiều, vì những thứ như tái cấu trúc có thể được thực hiện rất đơn giản vì công cụ hiểu được cú pháp đầy đủ, bao gồm cả thông tin meta (như nhận xét) và chỉ có thể làm việc trực tiếp với nó.


12

Một điểm khác biệt lớn mà tôi thấy: với CodeDom, mỗi khi bạn biên dịch một số C # hoặc VB.NET, nó sẽ xảy ra sai quy trình. CSC.exe hoặc VBC.exe là những công nhân thực sự đằng sau hiện trường.

Nếu bạn muốn xây dựng một dịch vụ, về kiến ​​trúc, khả năng mở rộng, sự cô lập, v.v. (bạn đề cập đến Azure), điều này không tốt lắm.

Với Roslyn, đó là quá trình.

Tôi cho rằng đây là một trong những lý do họ gọi nó là "Trình biên dịch như một dịch vụ".

Ngoài ra, CodeDom là một API tương đối kém, thiếu nhiều tính năng và không thực sự cập nhật, vì nó được thiết kế chủ yếu để hỗ trợ các nhà thiết kế Visual Studio UI tự động tạo mã. Tôi nghĩ Roslyn sẽ làm tốt hơn nhiều vì nó được viết bởi những người viết các trình biên dịch. Tôi hy vọng điều đó sẽ tạo ra sự khác biệt.

Tái bút: Một điểm khác biệt đáng chú ý so với CSC.exe và VBC.exe: Roslyn dường như là .NET thuần túy (và sử dụng CCI ).


8

Roslyn cho phép kiểm soát toàn bộ quá trình tốt hơn nhiều - ví dụ: bạn có thể phân tích chuỗi và thậm chí tạo mã bổ sung (ngay lập tức trong quá trình biên dịch dựa trên phân tích), v.v.

CodeDom là "chỉ sử dụng trình biên dịch" trong khi Roslyn là "trình biên dịch như một dịch vụ có toàn quyền truy cập vào các phần (phụ)" ... với Roslyn, bạn đang ở "bên trong trình biên dịch" và có thể xem mã trông như thế nào từ góc độ trình biên dịch cho phép bạn thay đổi mọi thứ theo những cách hiện không thể thực hiện được.

Ví dụ: bạn có thể sử dụng Roslyn để mở rộng C # - một thứ rất tiện dụng và tốt hơn nhiều so với trạng thái triển khai AOP hiện tại.

Để biết tổng quan về trạng thái Roslyn hiện tại và các cấp độ truy cập và kiểm soát khác nhau mà nó cung cấp, hãy xem http://msdn.microsoft.com/en-us/hh500769

CẬP NHẬT

Microsoft vừa cung cấp một CTP mới với các tính năng bổ sung và nhiều thay đổi / bổ sung API. Thông tin chi tiết xem tại đây .


1
Trên thực tế, không đúng khi bạn có thể sử dụng Roslyn để mở rộng C # với các từ khóa bổ sung.
Dustin Campbell

cảm ơn ... đã sửa ... mặc dù không phải trong bản phát hành đầu tiên, tôi khá rằng điều này sẽ khả thi ...
Yahia

2
@DustinCampbell, Điều gì sẽ xảy ra nếu bạn xử lý bất kỳ lỗi trình biên dịch nào mà từ khóa giả gây ra do tạo mã?
Rodrick Chapman

3
Bạn cần phải viết lại trước khi chuyển nó vào trình biên dịch. Đầu tiên, phân tích cú pháp mã với các từ khóa đặc biệt của bạn. Mã sẽ phân tích cú pháp và, trừ khi trình phân tích cú pháp không thể tạo đầu hoặc đuôi của nó, các từ khóa không hợp lệ sẽ hiển thị dưới dạng SkippedTokenTrivia trong cây kết quả. Sau đó, phát hiện các từ khóa bị bỏ qua và viết lại cây bằng mã hợp lệ (ví dụ: dệt AOP). Cuối cùng, chuyển cây mới vào trình biên dịch. Tuy nhiên, đây chắc chắn là một bản hack và nó không được đảm bảo sẽ hoạt động với các phiên bản Roslyn trong tương lai. Ví dụ: trình phân tích cú pháp có thể không tạo ra cùng một cây cho mã bị hỏng trong các bản phát hành trong tương lai.
Dustin Campbell

@DustinCampbell: nhưng liệu có SOMETHING cho phép dệt AOP trong trận chung kết Roslyn không? Công việc dệt Mono.Cecil INPC của tôi cũng hoạt động tốt, nhưng nếu tôi có thể viết public notifying string Name {get;set;}thì điều đó còn tuyệt vời hơn
TDaver
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.