Lezen in het Engels Bewerken

Share via


Attribute.IsDefined Method

Definition

Determines whether any custom attributes of a specified type are applied to an assembly, module, type member, or method parameter.

Overloads

IsDefined(ParameterInfo, Type, Boolean)

Determines whether any custom attributes are applied to a method parameter. Parameters specify the method parameter, the type of the custom attribute to search for, and whether to search ancestors of the method parameter.

IsDefined(Module, Type, Boolean)

Determines whether any custom attributes are applied to a module. Parameters specify the module, the type of the custom attribute to search for, and an ignored search option.

IsDefined(MemberInfo, Type, Boolean)

Determines whether any custom attributes are applied to a member of a type. Parameters specify the member, the type of the custom attribute to search for, and whether to search ancestors of the member.

IsDefined(Assembly, Type, Boolean)

Determines whether any custom attributes are applied to an assembly. Parameters specify the assembly, the type of the custom attribute to search for, and an ignored search option.

IsDefined(MemberInfo, Type)

Determines whether any custom attributes are applied to a member of a type. Parameters specify the member, and the type of the custom attribute to search for.

IsDefined(Module, Type)

Determines whether any custom attributes of a specified type are applied to a module. Parameters specify the module, and the type of the custom attribute to search for.

IsDefined(Assembly, Type)

Determines whether any custom attributes are applied to an assembly. Parameters specify the assembly, and the type of the custom attribute to search for.

IsDefined(ParameterInfo, Type)

Determines whether any custom attributes are applied to a method parameter. Parameters specify the method parameter, and the type of the custom attribute to search for.

IsDefined(ParameterInfo, Type, Boolean)

Source:
Attribute.CoreCLR.cs
Source:
Attribute.CoreCLR.cs
Source:
Attribute.CoreCLR.cs

Determines whether any custom attributes are applied to a method parameter. Parameters specify the method parameter, the type of the custom attribute to search for, and whether to search ancestors of the method parameter.

C#
public static bool IsDefined (System.Reflection.ParameterInfo element, Type attributeType, bool inherit);

Parameters

element
ParameterInfo

An object derived from the ParameterInfo class that describes a parameter of a member of a class.

attributeType
Type

The type, or a base type, of the custom attribute to search for.

inherit
Boolean

If true, specifies to also search the ancestors of element for custom attributes.

Returns

true if a custom attribute of type attributeType is applied to element; otherwise, false.

Exceptions

element or attributeType is null.

attributeType is not derived from Attribute.

element is not a method, constructor, or type.

Examples

The following code example illustrates the use of IsDefined, taking a ParameterInfo as a parameter.

C#
using System;
using System.Reflection;

namespace IsDef5CS
{
    public class TestClass
    {
        // Assign a ParamArray attribute to the parameter using the keyword.
        public void Method1(params String[] args)
        {}
    }

    public class DemoClass
    {
        static void Main(string[] args)
        {
            // Get the class type to access its metadata.
            Type clsType = typeof(TestClass);
            // Get the MethodInfo object for Method1.
            MethodInfo mInfo = clsType.GetMethod("Method1");
            // Get the ParameterInfo array for the method parameters.
            ParameterInfo[] pInfo = mInfo.GetParameters();
            if (pInfo != null)
            {
                // See if the ParamArray attribute is defined.
                bool isDef = Attribute.IsDefined(pInfo[0],
                                                 typeof(ParamArrayAttribute));
                // Display the result.
                Console.WriteLine("The ParamArray attribute {0} defined for " +
                                  "parameter {1} of method {2}.",
                                  isDef ? "is" : "is not",
                                  pInfo[0].Name,
                                  mInfo.Name);
            }
            else
                Console.WriteLine("The parameters information could " +
                            "not be retrieved for method {0}.", mInfo.Name);
        }
    }
}

/*
 * Output:
 * The ParamArray attribute is defined for parameter args of method Method1.
 */

Applies to

.NET 9 en andere versies
Product Versies
.NET Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0, 2.1

IsDefined(Module, Type, Boolean)

Source:
Attribute.CoreCLR.cs
Source:
Attribute.CoreCLR.cs
Source:
Attribute.CoreCLR.cs

Determines whether any custom attributes are applied to a module. Parameters specify the module, the type of the custom attribute to search for, and an ignored search option.

C#
public static bool IsDefined (System.Reflection.Module element, Type attributeType, bool inherit);

Parameters

element
Module

An object derived from the Module class that describes a portable executable file.

attributeType
Type

The type, or a base type, of the custom attribute to search for.

inherit
Boolean

This parameter is ignored, and does not affect the operation of this method.

Returns

true if a custom attribute of type attributeType is applied to element; otherwise, false.

Exceptions

element or attributeType is null.

attributeType is not derived from Attribute.

Examples

The following code example illustrates the use of IsDefined, taking a Module as a parameter.

C#
using System;
using System.Diagnostics;

// Add the Debuggable attribute to the module.
[module:Debuggable(true, false)]
namespace IsDef2CS
{
    public class DemoClass
    {
        static void Main(string[] args)
        {
            // Get the class type to access its metadata.
            Type clsType = typeof(DemoClass);
            // See if the Debuggable attribute is defined for this module.
            bool isDef = Attribute.IsDefined(clsType.Module,
                typeof(DebuggableAttribute));
            // Display the result.
            Console.WriteLine("The Debuggable attribute {0} " +
                "defined for Module {1}.",
                isDef ? "is" : "is not",
                clsType.Module.Name);
            // If the attribute is defined, display the JIT settings.
            if (isDef)
            {
                // Retrieve the attribute itself.
                DebuggableAttribute dbgAttr = (DebuggableAttribute)
                    Attribute.GetCustomAttribute(clsType.Module,
                    typeof(DebuggableAttribute));
                if (dbgAttr != null)
                {
                    Console.WriteLine("JITTrackingEnabled is {0}.",
                        dbgAttr.IsJITTrackingEnabled);
                    Console.WriteLine("JITOptimizerDisabled is {0}.",
                        dbgAttr.IsJITOptimizerDisabled);
                }
                else
                    Console.WriteLine("The Debuggable attribute " +
                        "could not be retrieved.");
            }
        }
    }
}

/*
 * Output:
 * The Debuggable attribute is defined for Module IsDef2CS.exe.
 * JITTrackingEnabled is True.
 * JITOptimizerDisabled is False.
 */

Remarks

This method ignores the inherit parameter and does not search the ancestors of element for custom attributes.

Applies to

.NET 9 en andere versies
Product Versies
.NET Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0, 2.1

IsDefined(MemberInfo, Type, Boolean)

Source:
Attribute.CoreCLR.cs
Source:
Attribute.CoreCLR.cs
Source:
Attribute.CoreCLR.cs

Determines whether any custom attributes are applied to a member of a type. Parameters specify the member, the type of the custom attribute to search for, and whether to search ancestors of the member.

C#
public static bool IsDefined (System.Reflection.MemberInfo element, Type attributeType, bool inherit);

Parameters

element
MemberInfo

An object derived from the MemberInfo class that describes a constructor, event, field, method, type, or property member of a class.

attributeType
Type

The type, or a base type, of the custom attribute to search for.

inherit
Boolean

If true, specifies to also search the ancestors of element for custom attributes.

Returns

true if a custom attribute of type attributeType is applied to element; otherwise, false.

Exceptions

element or attributeType is null.

attributeType is not derived from Attribute.

element is not a constructor, method, property, event, type, or field.

Examples

The following code example illustrates the use of IsDefined, taking a MemberInfo as a parameter.

C#
using System;
using System.Reflection;

namespace IsDef4CS
{
    public class TestClass
    {
        // Assign the Obsolete attribute to a method.
        [Obsolete("This method is obsolete. Use Method2 instead.")]
        public void Method1()
        {}
        public void Method2()
        {}
    }

    public class DemoClass
    {
        static void Main(string[] args)
        {
            // Get the class type to access its metadata.
            Type clsType = typeof(TestClass);
            // Get the MethodInfo object for Method1.
            MethodInfo mInfo = clsType.GetMethod("Method1");
            // See if the Obsolete attribute is defined for this method.
            bool isDef = Attribute.IsDefined(mInfo, typeof(ObsoleteAttribute));
            // Display the result.
            Console.WriteLine("The Obsolete Attribute {0} defined for {1} of class {2}.",
                isDef ? "is" : "is not", mInfo.Name, clsType.Name);
            // If it's defined, display the attribute's message.
            if (isDef)
            {
                ObsoleteAttribute obsAttr =
                                 (ObsoleteAttribute)Attribute.GetCustomAttribute(
                                                    mInfo, typeof(ObsoleteAttribute));
                if (obsAttr != null)
                    Console.WriteLine("The message is: \"{0}\".",
                        obsAttr.Message);
                else
                    Console.WriteLine("The message could not be retrieved.");
            }
        }
    }
}

/*
 * Output:
 * The Obsolete Attribute is defined for Method1 of class TestClass.
 * The message is: "This method is obsolete. Use Method2 instead.".
 */

Remarks

Notitie

Starting with the .NET Framework version 2.0, this method returns true if a type, method, or constructor has security attributes stored in the new metadata format. Assemblies compiled with version 2.0 or later use the new format. Dynamic assemblies and assemblies compiled with earlier versions of the .NET Framework use the old XML format. See Emitting Declarative Security Attributes.

Applies to

.NET 9 en andere versies
Product Versies
.NET Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0, 2.1

IsDefined(Assembly, Type, Boolean)

Source:
Attribute.CoreCLR.cs
Source:
Attribute.CoreCLR.cs
Source:
Attribute.CoreCLR.cs

Determines whether any custom attributes are applied to an assembly. Parameters specify the assembly, the type of the custom attribute to search for, and an ignored search option.

C#
public static bool IsDefined (System.Reflection.Assembly element, Type attributeType, bool inherit);

Parameters

element
Assembly

An object derived from the Assembly class that describes a reusable collection of modules.

attributeType
Type

The type, or a base type, of the custom attribute to search for.

inherit
Boolean

This parameter is ignored, and does not affect the operation of this method.

Returns

true if a custom attribute of type attributeType is applied to element; otherwise, false.

Exceptions

element or attributeType is null.

attributeType is not derived from Attribute.

Examples

The following code example illustrates the use of IsDefined, taking an Assembly as a parameter.

C#
using System;
using System.Reflection;

// Add an AssemblyDescription attribute
[assembly: AssemblyDescription("A sample description")]
namespace IsDef1CS
{
    public class DemoClass
    {
        static void Main(string[] args)
        {
            // Get the class type to access its metadata.
            Type clsType = typeof(DemoClass);
            // Get the assembly object.
            Assembly assy = clsType.Assembly;
            // Store the assembly's name.
            String assyName = assy.GetName().Name;
            // See if the Assembly Description is defined.
            bool isdef = Attribute.IsDefined(assy,
                typeof(AssemblyDescriptionAttribute));
            if (isdef)
            {
                // Affirm that the attribute is defined.
                Console.WriteLine("The AssemblyDescription attribute " +
                    "is defined for assembly {0}.", assyName);
                // Get the description attribute itself.
                AssemblyDescriptionAttribute adAttr =
                    (AssemblyDescriptionAttribute)Attribute.GetCustomAttribute(
                    assy, typeof(AssemblyDescriptionAttribute));
                // Display the description.
                if (adAttr != null)
                    Console.WriteLine("The description is \"{0}\".",
                        adAttr.Description);
                else
                    Console.WriteLine("The description could not " +
                        "be retrieved.");
            }
            else
                Console.WriteLine("The AssemblyDescription attribute is not " +
                    "defined for assembly {0}.", assyName);
        }
    }
}

/*
 * Output:
 * The AssemblyDescription attribute is defined for assembly IsDef1CS.
 * The description is "A sample description".
 */

Remarks

Notitie

Starting with the .NET Framework version 2.0, this method returns true if the assembly has security attributes stored in the new metadata format. Assemblies compiled with version 2.0 or later use the new format. Dynamic assemblies and assemblies compiled with earlier versions of the .NET Framework use the old XML format. See Emitting Declarative Security Attributes.

Applies to

.NET 9 en andere versies
Product Versies
.NET Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0, 2.1

IsDefined(MemberInfo, Type)

Source:
Attribute.CoreCLR.cs
Source:
Attribute.CoreCLR.cs
Source:
Attribute.CoreCLR.cs

Determines whether any custom attributes are applied to a member of a type. Parameters specify the member, and the type of the custom attribute to search for.

C#
public static bool IsDefined (System.Reflection.MemberInfo element, Type attributeType);

Parameters

element
MemberInfo

An object derived from the MemberInfo class that describes a constructor, event, field, method, type, or property member of a class.

attributeType
Type

The type, or a base type, of the custom attribute to search for.

Returns

true if a custom attribute of type attributeType is applied to element; otherwise, false.

Exceptions

element or attributeType is null.

attributeType is not derived from Attribute.

element is not a constructor, method, property, event, type, or field.

Examples

The following code example illustrates the use of IsDefined, taking a MemberInfo as a parameter.

C#
using System;
using System.Reflection;

namespace IsDef4CS
{
    public class TestClass
    {
        // Assign the Obsolete attribute to a method.
        [Obsolete("This method is obsolete. Use Method2 instead.")]
        public void Method1()
        {}
        public void Method2()
        {}
    }

    public class DemoClass
    {
        static void Main(string[] args)
        {
            // Get the class type to access its metadata.
            Type clsType = typeof(TestClass);
            // Get the MethodInfo object for Method1.
            MethodInfo mInfo = clsType.GetMethod("Method1");
            // See if the Obsolete attribute is defined for this method.
            bool isDef = Attribute.IsDefined(mInfo, typeof(ObsoleteAttribute));
            // Display the result.
            Console.WriteLine("The Obsolete Attribute {0} defined for {1} of class {2}.",
                isDef ? "is" : "is not", mInfo.Name, clsType.Name);
            // If it's defined, display the attribute's message.
            if (isDef)
            {
                ObsoleteAttribute obsAttr =
                                 (ObsoleteAttribute)Attribute.GetCustomAttribute(
                                                    mInfo, typeof(ObsoleteAttribute));
                if (obsAttr != null)
                    Console.WriteLine("The message is: \"{0}\".",
                        obsAttr.Message);
                else
                    Console.WriteLine("The message could not be retrieved.");
            }
        }
    }
}

/*
 * Output:
 * The Obsolete Attribute is defined for Method1 of class TestClass.
 * The message is: "This method is obsolete. Use Method2 instead.".
 */

Remarks

The ancestors of element are searched for custom attributes.

Notitie

Starting with the .NET Framework version 2.0, this method returns true if a type, method, or constructor has security attributes stored in the new metadata format. Assemblies compiled with version 2.0 or later use the new format. Dynamic assemblies and assemblies compiled with earlier versions of the .NET Framework use the old XML format. See Emitting Declarative Security Attributes.

Applies to

.NET 9 en andere versies
Product Versies
.NET Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0, 2.1

IsDefined(Module, Type)

Source:
Attribute.CoreCLR.cs
Source:
Attribute.CoreCLR.cs
Source:
Attribute.CoreCLR.cs

Determines whether any custom attributes of a specified type are applied to a module. Parameters specify the module, and the type of the custom attribute to search for.

C#
public static bool IsDefined (System.Reflection.Module element, Type attributeType);

Parameters

element
Module

An object derived from the Module class that describes a portable executable file.

attributeType
Type

The type, or a base type, of the custom attribute to search for.

Returns

true if a custom attribute of type attributeType is applied to element; otherwise, false.

Exceptions

element or attributeType is null.

attributeType is not derived from Attribute.

Examples

The following code example illustrates the use of IsDefined, taking a Module as a parameter.

C#
using System;
using System.Diagnostics;

// Add the Debuggable attribute to the module.
[module:Debuggable(true, false)]
namespace IsDef2CS
{
    public class DemoClass
    {
        static void Main(string[] args)
        {
            // Get the class type to access its metadata.
            Type clsType = typeof(DemoClass);
            // See if the Debuggable attribute is defined for this module.
            bool isDef = Attribute.IsDefined(clsType.Module,
                typeof(DebuggableAttribute));
            // Display the result.
            Console.WriteLine("The Debuggable attribute {0} " +
                "defined for Module {1}.",
                isDef ? "is" : "is not",
                clsType.Module.Name);
            // If the attribute is defined, display the JIT settings.
            if (isDef)
            {
                // Retrieve the attribute itself.
                DebuggableAttribute dbgAttr = (DebuggableAttribute)
                    Attribute.GetCustomAttribute(clsType.Module,
                    typeof(DebuggableAttribute));
                if (dbgAttr != null)
                {
                    Console.WriteLine("JITTrackingEnabled is {0}.",
                        dbgAttr.IsJITTrackingEnabled);
                    Console.WriteLine("JITOptimizerDisabled is {0}.",
                        dbgAttr.IsJITOptimizerDisabled);
                }
                else
                    Console.WriteLine("The Debuggable attribute " +
                        "could not be retrieved.");
            }
        }
    }
}

/*
 * Output:
 * The Debuggable attribute is defined for Module IsDef2CS.exe.
 * JITTrackingEnabled is True.
 * JITOptimizerDisabled is False.
 */

Remarks

The ancestors of element are not searched for custom attributes.

Applies to

.NET 9 en andere versies
Product Versies
.NET Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0, 2.1

IsDefined(Assembly, Type)

Source:
Attribute.CoreCLR.cs
Source:
Attribute.CoreCLR.cs
Source:
Attribute.CoreCLR.cs

Determines whether any custom attributes are applied to an assembly. Parameters specify the assembly, and the type of the custom attribute to search for.

C#
public static bool IsDefined (System.Reflection.Assembly element, Type attributeType);

Parameters

element
Assembly

An object derived from the Assembly class that describes a reusable collection of modules.

attributeType
Type

The type, or a base type, of the custom attribute to search for.

Returns

true if a custom attribute of type attributeType is applied to element; otherwise, false.

Exceptions

element or attributeType is null.

attributeType is not derived from Attribute.

Examples

The following code example illustrates the use of IsDefined, taking an Assembly as a parameter.

C#
using System;
using System.Reflection;

// Add an AssemblyDescription attribute
[assembly: AssemblyDescription("A sample description")]
namespace IsDef1CS
{
    public class DemoClass
    {
        static void Main(string[] args)
        {
            // Get the class type to access its metadata.
            Type clsType = typeof(DemoClass);
            // Get the assembly object.
            Assembly assy = clsType.Assembly;
            // Store the assembly's name.
            String assyName = assy.GetName().Name;
            // See if the Assembly Description is defined.
            bool isdef = Attribute.IsDefined(assy,
                typeof(AssemblyDescriptionAttribute));
            if (isdef)
            {
                // Affirm that the attribute is defined.
                Console.WriteLine("The AssemblyDescription attribute " +
                    "is defined for assembly {0}.", assyName);
                // Get the description attribute itself.
                AssemblyDescriptionAttribute adAttr =
                    (AssemblyDescriptionAttribute)Attribute.GetCustomAttribute(
                    assy, typeof(AssemblyDescriptionAttribute));
                // Display the description.
                if (adAttr != null)
                    Console.WriteLine("The description is \"{0}\".",
                        adAttr.Description);
                else
                    Console.WriteLine("The description could not " +
                        "be retrieved.");
            }
            else
                Console.WriteLine("The AssemblyDescription attribute is not " +
                    "defined for assembly {0}.", assyName);
        }
    }
}

/*
 * Output:
 * The AssemblyDescription attribute is defined for assembly IsDef1CS.
 * The description is "A sample description".
 */

Remarks

Notitie

Starting with the .NET Framework version 2.0, this method returns true if the assembly has security attributes stored in the new metadata format. Assemblies compiled with version 2.0 or later use the new format. Dynamic assemblies and assemblies compiled with earlier versions of the .NET Framework use the old XML format. See Emitting Declarative Security Attributes.

Applies to

.NET 9 en andere versies
Product Versies
.NET Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0, 2.1

IsDefined(ParameterInfo, Type)

Source:
Attribute.CoreCLR.cs
Source:
Attribute.CoreCLR.cs
Source:
Attribute.CoreCLR.cs

Determines whether any custom attributes are applied to a method parameter. Parameters specify the method parameter, and the type of the custom attribute to search for.

C#
public static bool IsDefined (System.Reflection.ParameterInfo element, Type attributeType);

Parameters

element
ParameterInfo

An object derived from the ParameterInfo class that describes a parameter of a member of a class.

attributeType
Type

The type, or a base type, of the custom attribute to search for.

Returns

true if a custom attribute of type attributeType is applied to element; otherwise, false.

Exceptions

element or attributeType is null.

attributeType is not derived from Attribute.

Examples

The following code example illustrates the use of IsDefined, taking a ParameterInfo as a parameter.

C#
using System;
using System.Reflection;

namespace IsDef5CS
{
    public class TestClass
    {
        // Assign a ParamArray attribute to the parameter using the keyword.
        public void Method1(params String[] args)
        {}
    }

    public class DemoClass
    {
        static void Main(string[] args)
        {
            // Get the class type to access its metadata.
            Type clsType = typeof(TestClass);
            // Get the MethodInfo object for Method1.
            MethodInfo mInfo = clsType.GetMethod("Method1");
            // Get the ParameterInfo array for the method parameters.
            ParameterInfo[] pInfo = mInfo.GetParameters();
            if (pInfo != null)
            {
                // See if the ParamArray attribute is defined.
                bool isDef = Attribute.IsDefined(pInfo[0],
                                                 typeof(ParamArrayAttribute));
                // Display the result.
                Console.WriteLine("The ParamArray attribute {0} defined for " +
                                  "parameter {1} of method {2}.",
                                  isDef ? "is" : "is not",
                                  pInfo[0].Name,
                                  mInfo.Name);
            }
            else
                Console.WriteLine("The parameters information could " +
                            "not be retrieved for method {0}.", mInfo.Name);
        }
    }
}

/*
 * Output:
 * The ParamArray attribute is defined for parameter args of method Method1.
 */

Remarks

The ancestors of element are searched for custom attributes.

Applies to

.NET 9 en andere versies
Product Versies
.NET Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0, 2.1