| File: Argument{T}.cs | Web Access |
| Project: src\command-line-api\src\System.CommandLine\System.CommandLine.csproj (System.CommandLine) |
// Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.Generic; using System.CommandLine.Parsing; using System.Diagnostics.CodeAnalysis; namespace System.CommandLine { /// <inheritdoc cref="Argument" /> public class Argument<T> : Argument { private Func<ArgumentResult, T?>? _customParser; private Func<ArgumentResult, T>? _defaultValueFactory; /// <summary> /// Initializes a new instance of the Argument class. /// </summary> /// <param name="name">The name of the argument. This name can be used to look up the parsed value and is displayed in help.</param> public Argument(string name) : base(name) { } /// <summary> /// Gets or sets the delegate to invoke to create the default value. /// </summary> /// <remarks> /// This delegate is invoked when there was no parse input provided for given Argument. /// The same instance can be set as <see cref="CustomParser"/>. In that case, /// the delegate is also invoked when an input was provided. /// </remarks> public Func<ArgumentResult, T>? DefaultValueFactory { get { if (_defaultValueFactory is null) { if (this is Argument<bool> boolArgument) { boolArgument.DefaultValueFactory = _ => false; } } return _defaultValueFactory; } set => _defaultValueFactory = value; } /// <summary> /// Gets or sets a custom argument parser. /// </summary> /// <remarks> /// The custom parser is invoked when there was parse input provided for a given Argument. /// The same instance can be set as <see cref="DefaultValueFactory"/>; in that case, /// the delegate is also invoked when no input was provided. /// </remarks> public Func<ArgumentResult, T?>? CustomParser { get => _customParser; set { _customParser = value; if (value is not null) { ConvertArguments = (ArgumentResult argumentResult, out object? parsedValue) => { int errorsBefore = argumentResult.SymbolResultTree.ErrorCount; var result = value(argumentResult); if (errorsBefore == argumentResult.SymbolResultTree.ErrorCount) { parsedValue = result; return true; } else { parsedValue = default(T)!; return false; } }; } else { ConvertArguments = null; } } } /// <inheritdoc /> public override Type ValueType => typeof(T); /// <inheritdoc /> public override bool HasDefaultValue => DefaultValueFactory is not null; internal override object? GetDefaultValue(ArgumentResult argumentResult) { if (DefaultValueFactory is null) { throw new InvalidOperationException($"Argument \"{Name}\" does not have a default value"); } return DefaultValueFactory.Invoke(argumentResult); } [UnconditionalSuppressMessage("ReflectionAnalysis", "IL3050", Justification = "https://github.com/dotnet/command-line-api/issues/1638")] [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2091", Justification = "https://github.com/dotnet/command-line-api/issues/1638")] internal static T? CreateDefaultValue() { if (default(T) is null && typeof(T) != typeof(string)) { #if NET7_0_OR_GREATER if (typeof(T).IsSZArray) #else if (typeof(T).IsArray && typeof(T).GetArrayRank() == 1) #endif { return (T?)(object)Array.CreateInstance(typeof(T).GetElementType()!, 0); } else if (typeof(T).IsConstructedGenericType) { var genericTypeDefinition = typeof(T).GetGenericTypeDefinition(); if (genericTypeDefinition == typeof(IEnumerable<>) || genericTypeDefinition == typeof(IList<>) || genericTypeDefinition == typeof(ICollection<>)) { return (T?)(object)Array.CreateInstance(typeof(T).GenericTypeArguments[0], 0); } if (genericTypeDefinition == typeof(List<>)) { return Activator.CreateInstance<T>(); } } } return default; } } }