2015-09-19 12 views
6

Sử dụng Roslyn, tôi tạo mã C# dựa trên biểu tượng phương pháp được phân tích cú pháp từ mã ngoài kiểm soát của tôi. Do đó, phương thức có thể có bất kỳ số lượng đối số nào. Mã tôi tạo ra bao gồm một biểu thức lambda mà phải mất một đối số duy nhất, chẳng hạn như:Xác định tên số nhận dạng duy nhất bằng cách sử dụng Roslyn

// I'm generating code like this 
public void SomeMethod() 
{ 
    DoSomething(x => x.Foo()); 
} 

Một vấn đề tiềm năng với mã này được nếu phương pháp chứa bao gồm một tham số gọi x:

// my code generator might produce this 
public void SomeMethod(int x) 
{ 
    DoSomething(x => x.Foo()); 
} 

Mã này dẫn đến lỗi:

A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter

Đủ công bằng.

Để giải quyết vấn đề này, tôi đã nghĩ mình có thể bắt đầu với tên mã định danh x, sử dụng SemanticModel.LookupSymbols để xem liệu nó đã được xác định chưa. Nếu có, hãy thêm _ (để nhận _x) và lặp lại.

Nhưng đây có phải là cách tốt nhất không? Và nếu có, làm cách nào để sử dụng LookupSymbols khi tất cả những gì tôi có là biểu tượng phương pháp?

Một tùy chọn khác mà tôi cho là chỉ sử dụng bộ sưu tập Parameters trong biểu tượng phương thức. Thay vào đó, tôi có thể thực hiện cùng một thuật toán lựa chọn tên. Nhưng điều này có đủ không? Ví dụ:

private static string GetIdentifierName(IMethodSymbol within) 
{ 
    var proposed = "x"; 

    while (within.Parameters.Any(x => x.Name == proposed)) 
    { 
     proposed = "_" + proposed; 
    } 

    return proposed; 
} 
+0

Khi tôi phải xác minh dựa vào các số nhận dạng tham số phương thức, tôi cũng sử dụng phương pháp thứ hai của bạn. –

+0

Bạn cũng cần kiểm tra người dân địa phương. – SLaks

+0

@Slaks: Tôi đang tạo phương pháp, vì vậy tôi kiểm soát được người dân địa phương (không có). –

Trả lời

1

Sử dụng SemanticModel.LookupSymbols có vẻ như là một cách tiếp cận tốt. Đây là cách Visual Studio di chuyển mã đã chọn sang các phương thức mới. Xem lớp nội bộ UniqueNameGenerator ở Roslyn.

Cách sử dụng LookupSymbols khi tất cả những gì bạn có là biểu tượng phương pháp: bạn đã thêm DoSomething(x => x.Foo()); được tạo vào mã, vì vậy bạn không chỉ là biểu tượng phương pháp, phải không? Nhưng trong mọi trường hợp, từ IMethodSymbol bạn có thể nhận được DeclaringSyntaxReferences để truy cập các nút cú pháp tương ứng.

Các vấn đề liên quan