Ответ 1
Я бы ожидал некоторых подробностей о параметрах типа
Результат nameof. Результат nameof зависит от символов, которые его аргумент, связанный с:
Один или несколько членов: если все члены имеют одинаковое имя метаданных, результатом nameof является это имя; в противном случае это ошибка "This аргумент ссылается на несколько элементов с разными именами". имя метаданных члена я
or
я < isA1... AK > `просто "я" после стандартного преобразования идентификаторов.
Параметр <T>
удаляется из-за стандартных преобразований идентификатора (раздел § 2.2.4 в спецификации С#), который не позволяет <>
как действительные идентификаторы. Сначала удаляется любое из ведущих @, затем удаляются последовательности Unicode, а затем удаляются любые символы форматирования. Это, конечно же, происходит во время компиляции. Вы также можете увидеть это при попытке распечатать имя родового типа:
typeof(List<string>).Name;
приведет к:
List`1
Это потому, что nameof является конструкцией времени компиляции и генериками типы инициализируются во время выполнения? Или есть другие ограничения?
Вторая ошибка указана как недопустимая по дизайну, чтобы избежать осложнений разрешения перегрузки внутри nameof
:
Разрешить общие аргументы типа? Предположительно "да" при именовании типа так как это выражение уже работает. И предположительно "нет". при присвоении имени группе методов, поскольку аргументы типа используются/выводятся во время разрешения перегрузки, и было бы справиться с этим в nameof.
Мы ясно видим это в кодовой базе roslyn:
private BoundExpression BindNameofOperatorInternal(InvocationExpressionSyntax node,
DiagnosticBag diagnostics)
{
CheckFeatureAvailability(node.GetLocation(), MessageID.IDS_FeatureNameof, diagnostics);
var argument = node.ArgumentList.Arguments[0].Expression;
string name = "";
// We relax the instance-vs-static requirement for top-level member access expressions by creating a NameofBinder binder.
var nameofBinder = new NameofBinder(argument, this);
var boundArgument = nameofBinder.BindExpression(argument, diagnostics);
if (!boundArgument.HasAnyErrors && CheckSyntaxForNameofArgument(argument, out name, diagnostics) && boundArgument.Kind == BoundKind.MethodGroup)
{
var methodGroup = (BoundMethodGroup)boundArgument;
if (!methodGroup.TypeArgumentsOpt.IsDefaultOrEmpty)
{
// method group with type parameters not allowed
diagnostics.Add(ErrorCode.ERR_NameofMethodGroupWithTypeParameters, argument.Location);
}
else
{
nameofBinder.EnsureNameofExpressionSymbols(methodGroup, diagnostics);
}
}
return new BoundNameOfOperator(node, boundArgument, ConstantValue.Create(name), Compilation.GetSpecialType(SpecialType.System_String));
}