Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu öğreticide Söz Dizimi API'sini bildiğiniz varsayılır. Söz dizimi analizini kullanmaya başlama makalesi yeterli giriş sağlar.
Bu öğreticide Sembol ve Bağlama API'lerini keşfedersiniz. Bu API'ler bir programın anlamsal anlamı hakkında bilgi sağlar. Bunlar, programınızdaki herhangi bir simgeyle temsil edilen türler hakkında soru sormanıza ve yanıtlamanıza olanak tanır.
.NET Derleyici Platformu SDK'sını yüklemeniz gerekir:
Yükleme yönergeleri - Visual Studio Yükleyicisi
Visual Studio Yükleyicisi'nde.NET Derleyici Platformu SDK'sını bulmanın iki farklı yolu vardır:
Visual Studio Yükleyicisi - İş Yükleri görünümünü kullanarak yükleme
.NET Derleyici Platformu SDK'sı, Visual Studio uzantısı geliştirme iş yükünün bir parçası olarak otomatik olarak seçilmez. İsteğe bağlı bir bileşen olarak seçmelisiniz.
- Visual Studio Yükleyicisi'nin çalıştırılması
- Değiştir'i seçin
- Visual Studio uzantısı geliştirme iş yükünü denetleyin.
- Özet ağacında Visual Studio uzantısı geliştirme düğümünü açın.
- .NET Derleyici Platformu SDK'sı kutusunun işaretli olduğundan emin olun.
- Değiştir'i seçin.
İsteğe bağlı olarak , DGML düzenleyicisinin görselleştiricide grafikleri görüntülemesini de istersiniz:
- Özet ağacında Tek tek bileşenler düğümünü açın.
- DGML düzenleyicisi kutusunu işaretleyin
Visual Studio Yükleyicisi - Tek bileşenler sekmesini kullanarak yükleme
- Visual Studio Yükleyicisi'nin çalıştırılması
- Değiştir'i seçin
- Tek tek bileşenler sekmesini seçin
- .NET Derleyici Platformu SDK'sı kutusunu işaretleyin. Derleyiciler, derleme araçları ve çalışma zamanları bölümünün altında en üstte bulabilirsiniz.
- Değiştir'i seçin.
İsteğe bağlı olarak , DGML düzenleyicisinin görselleştiricide grafikleri görüntülemesini de istersiniz:
- DGML düzenleyicisi kutusunu işaretleyin. Kod araçları bölümünde bulabilirsiniz.
Derlemeleri ve Sembolleri Anlama
.NET Derleyici SDK'sı ile daha fazla çalışırken Söz Dizimi API'siyle Anlam API'si arasındaki farkları daha iyi biliyorsunuz. Söz Dizimi API'si, bir programın yapısına bakmanızı sağlar. Ancak, genellikle bir programın semantiği veya anlamı hakkında daha zengin bilgiler istersiniz. Visual Basic veya C# kodunun gevşek bir kod dosyası veya parçacığı tek tek analiz edilebilir ancak vakumda "bu değişkenin türü nedir" gibi sorular sormak anlamlı değildir. Tür adının anlamı derleme başvurularına, ad alanı içeri aktarmalarına veya diğer kod dosyalarına bağlı olabilir. Bu sorular semantik API,özellikle sınıfı kullanılarak yanıtlandırılır Microsoft.CodeAnalysis.Compilation .
örneği Compilation , derleyici tarafından görüldüğü gibi tek bir projeye benzer ve Visual Basic veya C# programı derlemek için gereken her şeyi temsil eder. Derleme derlenecek kaynak dosya kümesini, derleme başvurularını ve derleyici seçeneklerini içerir. Bu bağlamdaki diğer tüm bilgileri kullanarak kodun anlamını anlayabilirsiniz. A Compilation , adların ve diğer ifadelerin başvurdığı türler, ad alanları, üyeler ve değişkenler gibi varlıklar olan Sembolleri bulmanıza olanak tanır. Adları ve ifadeleri Simgelerle ilişkilendirme işlemi Bağlama olarak adlandırılır.
gibi Microsoft.CodeAnalysis.SyntaxTree, Compilation dile özgü türevleri olan soyut bir sınıftır. "Derleme işlemi örneği oluştururken, Microsoft.CodeAnalysis.CSharp.CSharpCompilation (veya Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilation) sınıfında bir fabrika yöntemi çağırmanız gerekmektedir."
Sembolleri sorgulama
Bu öğreticide" Merhaba Dünya" programına yeniden bakacaksınız. Bu kez, bu simgelerin hangi türleri temsil ettiğinizi anlamak için programdaki simgeleri sorgularsınız. Ad alanı içindeki türleri sorgular ve bir türdeki kullanılabilir yöntemleri bulmayı öğrenirsiniz.
Bu örneğin tamamlanmış kodunu GitHub depomuzda görebilirsiniz.
Uyarı
Söz Dizimi Ağacı türleri, programın farklı konumlarında geçerli olan farklı söz dizimi öğelerini açıklamak için devralmayı kullanır. Bu API'lerin kullanılması genellikle özellikleri veya koleksiyon üyelerini belirli türetilmiş türlere atama anlamına gelir. Aşağıdaki örneklerde, atama ve tür dönüşümleri açık şekilde belirlenmiş türdeki değişkenler kullanılarak ayrı deyimler olarak ele alınmaktadır. API'nin dönüş türlerini ve döndürülen nesnelerin çalışma zamanı türünü görmek için kodu okuyabilirsiniz. Uygulamada, örtük olarak yazılan değişkenleri kullanmak ve incelenen nesne türünü tanımlamak için API adlarına güvenmek daha yaygındır.
Yeni bir C# Stand-Alone Kod Çözümleme Aracı projesi oluşturun:
- Visual Studio'daDosya>Yeni>Proje'yi seçerek Yeni Proje iletişim kutusu açılır.
- Visual C#>Genişletilebilirlik altında Bağımsız Kod Analiz Aracı seçin.
- Projenize "SemanticQuickStart" adını verin ve Tamam'a tıklayın.
Daha önce gösterilen temel "Merhaba Dünya!" programını analiz edeceksin.
Hello World programının metnini sınıfınızda Program sabit olarak ekleyin:
const string programText =
@"using System;
using System.Collections.Generic;
using System.Text;
namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(""Hello, World!"");
}
}
}";
Ardından, sabitteki kod metninin programText söz dizimi ağacını oluşturmak için aşağıdaki kodu ekleyin. Yönteminize Main aşağıdaki satırı ekleyin:
SyntaxTree tree = CSharpSyntaxTree.ParseText(programText);
CompilationUnitSyntax root = tree.GetCompilationUnitRoot();
Ardından, önceden oluşturduğunuz ağaçtan bir CSharpCompilation oluşturun. "Hello World" örneği String ve Console türlerine dayanır. Derlemenizde bu iki türü bildiren derlemeye başvurmanız gerekir. Söz dizimi ağacınızın derlemesini oluşturmak için uygun derlemeye başvuru dahil olmak üzere aşağıdaki satırı Main yöntemine ekleyin.
var compilation = CSharpCompilation.Create("HelloWorld")
.AddReferences(MetadataReference.CreateFromFile(
typeof(string).Assembly.Location))
.AddSyntaxTrees(tree);
Bu yöntem derlemeye CSharpCompilation.AddReferences referanslar ekler. MetadataReference.CreateFromFile yöntem derlemeyi başvuru olarak yükler.
Anlam modelini sorgulama
Compilation'ye sahip olduktan sonra, o Compilation içindeki herhangi bir SyntaxTree için SemanticModel isteyebilirsiniz. Semantik modeli, normalde IntelliSense'ten alabileceğiniz tüm bilgilerin kaynağı olarak düşünebilirsiniz. , SemanticModel "Bu konumda hangi adlar kapsam içinde?", "Bu yöntemden hangi üyelere erişilebilir?", "Bu metin bloğunda hangi değişkenler kullanılıyor?" ve "Bu ad/ifade neye başvurur?" gibi soruları yanıtlayabilir. Anlamsal modeli oluşturmak için şu deyimi ekleyin:
SemanticModel model = compilation.GetSemanticModel(tree);
Ad bağlama
Compilation , SyntaxTree'den SemanticModel öğesini oluşturur. Modeli oluşturduktan sonra, modeli sorgulayarak ilk using yönergeyi bulabilir ve System ad alanı için sembol bilgilerini alabilirsiniz. Semantik modeli oluşturmak ve ilk Main yönergenin simgesini almak için yönteminize using şu iki satırı ekleyin:
// Use the syntax tree to find "using System;"
UsingDirectiveSyntax usingSystem = root.Usings[0];
NameSyntax systemName = usingSystem.Name;
// Use the semantic model for symbol information:
SymbolInfo nameInfo = model.GetSymbolInfo(systemName);
Yukarıdaki kod, ilk using yönergesinde adı, System ad alanından bir Microsoft.CodeAnalysis.SymbolInfo almak amacıyla nasıl bağlayacağını gösterir. Yukarıdaki kod, kodun yapısını bulmak için söz dizimi modelini kullandığınızı da gösterir; anlam modelini anlamını anlamak için kullanırsınız.
Söz dizimi modeli, using yönergesindeki System dizisini bulur.
Anlam modeli, ad alanında System tanımlanan türler hakkındaki tüm bilgilere sahiptir.
SymbolInfo nesnesinden SymbolInfo.Symbol özelliğini kullanarak Microsoft.CodeAnalysis.ISymbol öğesini elde edebilirsiniz. Bu özellik, bu ifadenin başvurduğu simgeyi döndürür. Hiçbir şeye başvurmayan ifadeler için (örneğin sayısal sabitler) bu özellik null olarak belirlenir.
SymbolInfo.Symbol null olmadığında, ISymbol.Kind simgenin türünü belirtir. Bu örnekte ISymbol.Kind özelliği bir SymbolKind.Namespace'dir. aşağıdaki kodu Main yönteminize ekleyin. Ad alanı System için simgeyi alır ve sonra System ad alanında bildirilen tüm alt ad alanlarını görüntüler.
var systemSymbol = (INamespaceSymbol?)nameInfo.Symbol;
if (systemSymbol?.GetNamespaceMembers() is not null)
{
foreach (INamespaceSymbol ns in systemSymbol?.GetNamespaceMembers()!)
{
Console.WriteLine(ns);
}
}
Programı çalıştırdığınızda aşağıdaki çıkışı görmeniz gerekir:
System.Collections
System.Configuration
System.Deployment
System.Diagnostics
System.Globalization
System.IO
System.Numerics
System.Reflection
System.Resources
System.Runtime
System.Security
System.StubHelpers
System.Text
System.Threading
Press any key to continue . . .
Uyarı
Çıktı, System adlı ad alanının alt ad alanı olan her ad alanını içermez. Bu derlemede bulunan ve yalnızca System.String'nin bildirildiği derlemeye başvuran tüm ad alanlarını görüntüler. Diğer derlemelerde bildirilen ad alanları bu derleme tarafından bilinmemektedir
Bir ifadeyi bağlama
Yukarıdaki kod, bir isme bağlanarak bir simgenin nasıl bulunacağını gösterir. C# programında ad olmayan, bağlanabilen başka ifadeler de vardır. Bu özelliği göstermek için basit bir dize sabitine bağlantı erişimi sağlayalım.
"Merhaba Dünya" programı, konsolunda görüntülenen "Hello, World!" dizesini içerir Microsoft.CodeAnalysis.CSharp.Syntax.LiteralExpressionSyntax.
Programda tek metin sabitini bularak "Hello, World!" dizesini bulursunuz. Ardından söz dizimi düğümünü bulduktan sonra, söz dizimi modelinden söz dizimi için tür bilgilerini alın. Yönteminize Main aşağıdaki kodu ekleyin:
// Use the syntax model to find the literal string:
LiteralExpressionSyntax helloWorldString = root.DescendantNodes()
.OfType<LiteralExpressionSyntax>()
.Single();
// Use the semantic model for type information:
TypeInfo literalInfo = model.GetTypeInfo(helloWorldString);
yapısı, Microsoft.CodeAnalysis.TypeInfo değişmez değerin türüyle ilgili anlam bilgilerine erişim sağlayan bir TypeInfo.Type özellik içerir. Bu örnekte, türü budur string . Bu özelliği yerel bir değişkene atayan bir bildirim ekleyin:
var stringTypeSymbol = (INamedTypeSymbol?)literalInfo.Type;
Bu öğreticiyi tamamlamak için, string türünde bildirilen ve bir string döndüren tüm genel yöntemlerin bir sırasını oluşturan bir LINQ sorgusu oluşturalım. Bu sorgu karmaşık hale geldiğinden satır satır oluşturalım ve ardından tek bir sorgu olarak yeniden oluşturalım. Bu sorgunun kaynağı, türüne göre bildirilen tüm üyelerin string dizisidir:
var allMembers = stringTypeSymbol?.GetMembers();
Bu kaynak dizisi, özellikler ve alanlar da dahil olmak üzere tüm üyeleri içerir, bu nedenle Microsoft.CodeAnalysis.IMethodSymbol nesneleri olan öğeleri bulmak için ImmutableArray<T>.OfType yöntemini kullanarak filtreleyin.
var methods = allMembers?.OfType<IMethodSymbol>();
Ardından, yalnızca public olan ve bir string döndüren yöntemleri döndürmek için başka bir filtre ekleyin:
var publicStringReturningMethods = methods?
.Where(m => SymbolEqualityComparer.Default.Equals(m.ReturnType, stringTypeSymbol) &&
m.DeclaredAccessibility == Accessibility.Public);
Aşırı yüklemeleri kaldırarak yalnızca name özelliğini ve yalnızca benzersiz adları seçin:
var distinctMethods = publicStringReturningMethods?.Select(m => m.Name).Distinct();
Ayrıca LINQ sorgu söz dizimini kullanarak tam sorguyu derleyebilir ve ardından konsolunda tüm yöntem adlarını görüntüleyebilirsiniz:
foreach (string name in (from method in stringTypeSymbol?
.GetMembers().OfType<IMethodSymbol>()
where SymbolEqualityComparer.Default.Equals(method.ReturnType, stringTypeSymbol) &&
method.DeclaredAccessibility == Accessibility.Public
select method.Name).Distinct())
{
Console.WriteLine(name);
}
Programı derleyin ve çalıştırın. Aşağıdaki çıkışı görmeniz gerekir:
Join
Substring
Trim
TrimStart
TrimEnd
Normalize
PadLeft
PadRight
ToLower
ToLowerInvariant
ToUpper
ToUpperInvariant
ToString
Insert
Replace
Remove
Format
Copy
Concat
Intern
IsInterned
Press any key to continue . . .
Semantik API'sini kullanarak bu programın parçası olan semboller hakkında bilgi bulup görüntülediniz.