Почему я все еще получаю сообщение IL2104 после устранения всех других предупреждений об обрезке? [С#, .NET 8.0]C#

Место общения программистов C#
Anonymous
Почему я все еще получаю сообщение IL2104 после устранения всех других предупреждений об обрезке? [С#, .NET 8.0]

Сообщение Anonymous »

У меня есть библиотека, которая поддерживает .NET Standard 2.1 и .NET 8.0. Версия .NET 8.0 отмечена меткой true, а проект тестового триммера настроен по ссылке на IL2104 предупреждение
После настройки этой среды я обнаружил множество предупреждений и использовал DynamicallyAccessedMembers, RequiresUnreferencedCode и UnconditionalSuppressMessage для соответствующей аннотации моей библиотеки, пока все они не исчезли, за исключением самого IL2104.
Я все еще получаю это предупреждение после того, как избавился от всех остальных.
A:\Proj\lib\My.Lib\My.Lib\bin\Release\net8.0\My.Lib.dll : warning IL2104: Assembly 'My.Lib' produced trim warnings. For more information see https://aka.ms/dotnet-illink/libraries
[A:\Proj\lib\My.Lib\TrimmerBuilder\TrimmerBuilder.csproj]

Разве его уже не должно быть? Что я здесь делаю не так?

Обновить
Вот воспроизводимый пример в соответствии с просьбой. Имейте в виду, что это только одно из мест, где я использовал и аннотировал необрезаемые функции. Я не уверен, что это единственное место, из-за которого я получаю предупреждение, но сам по себе этот пример ведет себя так, как я описал выше.
(Дайте мне знать в комментариях если потребуется больше контекста, я отредактирую и обновлю вопрос)
ClassLibCode.cs
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace MinimalExample;
/// extension methods
public static class TypeXs
{
/// Returns whether the type is a closure class
public static bool IsClosureClass(this Type type)
{
if (type?.GetCustomAttribute() != null)
{
return type.Name.Contains("DisplayClass") || type.Name.Contains("Closure$");
}
return false;
}
/// Returns whether the type is anonymous
public static bool IsAnonymous(this Type type)
{
if (type?.GetCustomAttribute() != null)
{
return type.Name.Contains("Anonymous") && type.Name.Contains("") && !type.InheritsFromOrImplements();
}
return false;
}
/// Returns whether a type Inherits from or Implements another type
public static bool InheritsFromOrImplements(this Type type)
{
return typeof(T).IsAssignableFrom(type);
}
/// A struct containing types information in a nested array
public readonly struct NestedArrayType
{
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)]
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
public readonly Type? root;
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)]
public readonly Type current;
public NestedArrayType(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type? root,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type current
)
{
this.root = root;
this.current = current;
}
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
}
/// Returns all the nested types of an array of arrays
[RequiresUnreferencedCode(message: "Only flat arrays are supported, Nested ones are not supported")]
public static IEnumerable NestedArrayTypes([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] this Type type)
{
Type currentType = type;
while (currentType.IsArray)
{
Type nextType = currentType.GetElementType()!; // not null cuz we checked `IsArray` above
if (nextType.IsArray)
{
yield return new(root: null, current: currentType);
}
else
{
yield return new(root: nextType, current: currentType);
break;
}
currentType = nextType;
}
}
/// Return the non-generic part of the type name (before the tick (`) in generics)
public static string NonGenericName(this Type t)
{
return t.Name[..t.Name.IndexOf('`')];
}
/// doesn't return inheritted private fields on its own. This method recursively gathers all of them
public static IEnumerable FindMembersIncludingInheritedPrivates([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] this Type? type, MemberTypes memberTypes, BindingFlags bindingFlags, MemberFilter memberFilter, object? filterCriteria = null)
{
if (type == null || type == typeof(object) || !type.IsClass || type.IsInterface) { return Enumerable.Empty(); }
IEnumerable baseMembers = type.BaseType.FindMembersIncludingInheritedPrivates(memberTypes, bindingFlags, memberFilter, filterCriteria);
IEnumerable interfacesMembers = type.GetInterfaces().SelectMany(([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] x) => x.FindMembersIncludingInheritedPrivates(memberTypes, bindingFlags, memberFilter, filterCriteria));
IEnumerable currentMembers = type.FindMembers(memberTypes, bindingFlags, memberFilter, filterCriteria);
return baseMembers.Concat(interfacesMembers).Concat(currentMembers);
}
/// Returns a human-readable name for the type
[RequiresUnreferencedCode("Trimming is not supported on some types")]
public static string FriendlyName([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] this Type self)
{
if (self == null) { throw new ArgumentNullException(nameof(self)); }
if (self.IsClosureClass())
{
return "";
}
if (self.IsAnonymous())
{
return "{ " + string.Join(", ", Array.ConvertAll(self.GetProperties(),
([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] PropertyInfo p) =>
{
string name = p.Name;
string typename = "UnknownType";
return $"{typename} {name}";
}
)) + " }";
}
if (self.IsArray)
{
(string? left, string? right) = ("[", "]");
var nestedArrayTypes = self.NestedArrayTypes().ToList();
string arraySpecifiers = string.Join("", nestedArrayTypes.ConvertAll(
v => left + string.Join("", Enumerable.Repeat("", v.current.GetArrayRank())) + right
));
return nestedArrayTypes.Last().root!.FriendlyName() + arraySpecifiers;
}
if (self.IsGenericType)
{
if (self.GetGenericTypeDefinition() == typeof(Nullable))
{
return (Nullable.GetUnderlyingType(self) ?? self).FriendlyName() + "?";
}
if (self.IsGenericParameter)
{
return self.Name;
}
Type[] args = self.GetGenericArguments();
// var parts = self.GetGenericArguments().Joined(", ", t => t.FriendlyName()!);
string parts = string.Join(", ", Array.ConvertAll(self.GetGenericArguments(), ([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] t) => t.FriendlyName()!));
string nongenericName = self.NonGenericName();
return $"{nongenericName}";
}
else
{
return self.Name;
}
}
/// Returns a human-readable full-name for the type
[RequiresUnreferencedCode("Trimming is not supported on some types")]
public static string FriendlyFullName([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] this Type self)
{
return $"{self.Namespace}::{self.FriendlyName()}";
}
}

ClassLib.csproj



0.0.0.1
net8.0;netstandard2.1

true
enable
latest
true
true



true
true
false



true
true
portable
true
true
$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb



Trimmer.csproj


net8.0
true
true
Exe
enable
true
false








Подробнее здесь: https://stackoverflow.com/questions/790 ... warnings-c

Вернуться в «C#»