Используя API Roslyn, я попытался получить пространство имен нулевого типа структуры (с использованием isymbol.contingNamespace) и был удивлен, когда он вернул пространство имен системы. Это происходит только для нулевых структур, оно работает так же, как и ожидалось для нулевых классов и не нулевых структур.
Exe
net9.0
13
enable
enable
< /code>
program.cs:
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace StructNamespaceRepro;
class Program
{
static void Main(string[] args)
{
string sourceText = """
// missing nullable context only causes an error for SomeClass? but not for SomeStruct?
#nullable enable
namespace StructNamespaceRepro.SomeNamespace {
internal class SomeClass;
internal struct SomeStruct;
internal class ClassContainingFieldDeclarations {
private SomeClass? _someClass = new();
private SomeStruct _someNonNullStruct = default;
private SomeStruct? _someNullableStruct = default;
}
}
""";
// compile sourcetext and create semantic model
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(sourceText);
CSharpCompilation compilation = CSharpCompilation.Create("AssemblyName", [syntaxTree],
[
// add reference to corelib
MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
]);
SemanticModel semanticModel = compilation.GetSemanticModel(syntaxTree);
if (semanticModel.GetDiagnostics().Length > 0)
{
throw new Exception("errors in source text");
}
// bind structdeclaration
StructDeclarationSyntax structDeclaration =
syntaxTree.GetRoot().DescendantNodes().OfType().First();
ITypeSymbol structType = semanticModel.GetDeclaredSymbol(structDeclaration);
// bind field declarations
List symbols = syntaxTree.GetRoot().DescendantNodes()
.OfType()
.Select(x => x.Declaration.Variables[0]).Select(x => semanticModel.GetDeclaredSymbol(x))
.Select(x => (IFieldSymbol)x!).ToList();
IFieldSymbol someClassField = symbols.Single(x => x.Name == "_someClass");
IFieldSymbol someNonNullStructField = symbols.Single(x => x.Name == "_someNonNullStruct");
IFieldSymbol someNullableStructField = symbols.Single(x => x.Name == "_someNullableStruct");
// accessing struct declaration works
Console.WriteLine(structType); // StructNamespaceRepro.SomeNamespace.SomeStruct
Console.WriteLine(structType.ContainingNamespace); // StructNamespaceRepro.SomeNamespace
// accessing nullable class field works
Console.WriteLine(someClassField.Type); // StructNamespaceRepro.SomeNamespace.SomeClass?
Console.WriteLine(someClassField.Type.ContainingNamespace); // StructNamespaceRepro.SomeNamespace
// accessing non-nullable struct field works
Console.WriteLine(someNonNullStructField.Type); // StructNamespaceRepro.SomeNamespace.SomeStruct
Console.WriteLine(someNonNullStructField.Type.ContainingNamespace); // StructNamespaceRepro.SomeNamespace
// accessing nullable struct field returns System namespace?
Console.WriteLine(someNullableStructField.Type); // StructNamespaceRepro.SomeNamespace.SomeStruct?
Console.WriteLine(someNullableStructField.Type.ContainingNamespace); // System
Подробнее здесь: https://stackoverflow.com/questions/797 ... le-structs