Use TValue as the generic type parameter (#12953)

* Use TValue as the generic type parameter

Fixes https://github.com/aspnet/AspNetCore/issues/12926
This commit is contained in:
Pranav K 2019-08-09 10:19:33 -07:00 committed by GitHub
parent ecd6c11c46
commit dda84bc7fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 197 additions and 184 deletions

View File

@ -114,7 +114,7 @@ namespace Microsoft.AspNetCore.Components
public CascadingParameterAttribute() { }
public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
}
public partial class CascadingValue<T> : Microsoft.AspNetCore.Components.IComponent
public partial class CascadingValue<TValue> : Microsoft.AspNetCore.Components.IComponent
{
public CascadingValue() { }
[Microsoft.AspNetCore.Components.ParameterAttribute]
@ -124,7 +124,7 @@ namespace Microsoft.AspNetCore.Components
[Microsoft.AspNetCore.Components.ParameterAttribute]
public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
[Microsoft.AspNetCore.Components.ParameterAttribute]
public T Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
public TValue Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
public void Attach(Microsoft.AspNetCore.Components.RenderHandle renderHandle) { }
public System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters) { throw null; }
}
@ -188,17 +188,17 @@ namespace Microsoft.AspNetCore.Components
public Microsoft.AspNetCore.Components.EventCallback Create(object receiver, System.Func<object, System.Threading.Tasks.Task> callback) { throw null; }
public Microsoft.AspNetCore.Components.EventCallback Create(object receiver, System.Func<System.Threading.Tasks.Task> callback) { throw null; }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public Microsoft.AspNetCore.Components.EventCallback<T> CreateInferred<T>(object receiver, System.Action<T> callback, T value) { throw null; }
public Microsoft.AspNetCore.Components.EventCallback<TValue> CreateInferred<TValue>(object receiver, System.Action<TValue> callback, TValue value) { throw null; }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public Microsoft.AspNetCore.Components.EventCallback<T> CreateInferred<T>(object receiver, System.Func<T, System.Threading.Tasks.Task> callback, T value) { throw null; }
public Microsoft.AspNetCore.Components.EventCallback<TValue> CreateInferred<TValue>(object receiver, System.Func<TValue, System.Threading.Tasks.Task> callback, TValue value) { throw null; }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public Microsoft.AspNetCore.Components.EventCallback<T> Create<T>(object receiver, Microsoft.AspNetCore.Components.EventCallback callback) { throw null; }
public Microsoft.AspNetCore.Components.EventCallback<TValue> Create<TValue>(object receiver, Microsoft.AspNetCore.Components.EventCallback callback) { throw null; }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public Microsoft.AspNetCore.Components.EventCallback<T> Create<T>(object receiver, Microsoft.AspNetCore.Components.EventCallback<T> callback) { throw null; }
public Microsoft.AspNetCore.Components.EventCallback<T> Create<T>(object receiver, System.Action callback) { throw null; }
public Microsoft.AspNetCore.Components.EventCallback<T> Create<T>(object receiver, System.Action<T> callback) { throw null; }
public Microsoft.AspNetCore.Components.EventCallback<T> Create<T>(object receiver, System.Func<System.Threading.Tasks.Task> callback) { throw null; }
public Microsoft.AspNetCore.Components.EventCallback<T> Create<T>(object receiver, System.Func<T, System.Threading.Tasks.Task> callback) { throw null; }
public Microsoft.AspNetCore.Components.EventCallback<TValue> Create<TValue>(object receiver, Microsoft.AspNetCore.Components.EventCallback<TValue> callback) { throw null; }
public Microsoft.AspNetCore.Components.EventCallback<TValue> Create<TValue>(object receiver, System.Action callback) { throw null; }
public Microsoft.AspNetCore.Components.EventCallback<TValue> Create<TValue>(object receiver, System.Action<TValue> callback) { throw null; }
public Microsoft.AspNetCore.Components.EventCallback<TValue> Create<TValue>(object receiver, System.Func<System.Threading.Tasks.Task> callback) { throw null; }
public Microsoft.AspNetCore.Components.EventCallback<TValue> Create<TValue>(object receiver, System.Func<TValue, System.Threading.Tasks.Task> callback) { throw null; }
}
public static partial class EventCallbackFactoryBinderExtensions
{
@ -241,13 +241,13 @@ namespace Microsoft.AspNetCore.Components
public System.Threading.Tasks.Task InvokeAsync(object arg) { throw null; }
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public readonly partial struct EventCallback<T>
public readonly partial struct EventCallback<TValue>
{
private readonly object _dummy;
public static readonly Microsoft.AspNetCore.Components.EventCallback<T> Empty;
public static readonly Microsoft.AspNetCore.Components.EventCallback<TValue> Empty;
public EventCallback(Microsoft.AspNetCore.Components.IHandleEvent receiver, System.MulticastDelegate @delegate) { throw null; }
public bool HasDelegate { get { throw null; } }
public System.Threading.Tasks.Task InvokeAsync(T arg) { throw null; }
public System.Threading.Tasks.Task InvokeAsync(TValue arg) { throw null; }
}
public partial interface IComponent
{
@ -365,11 +365,11 @@ namespace Microsoft.AspNetCore.Components
public static Microsoft.AspNetCore.Components.ParameterView Empty { get { throw null; } }
public static Microsoft.AspNetCore.Components.ParameterView FromDictionary(System.Collections.Generic.IDictionary<string, object> parameters) { throw null; }
public Microsoft.AspNetCore.Components.ParameterView.Enumerator GetEnumerator() { throw null; }
public T GetValueOrDefault<T>(string parameterName) { throw null; }
public T GetValueOrDefault<T>(string parameterName, T defaultValue) { throw null; }
public TValue GetValueOrDefault<TValue>(string parameterName) { throw null; }
public TValue GetValueOrDefault<TValue>(string parameterName, TValue defaultValue) { throw null; }
public void SetParameterProperties(object target) { }
public System.Collections.Generic.IReadOnlyDictionary<string, object> ToDictionary() { throw null; }
public bool TryGetValue<T>(string parameterName, out T result) { throw null; }
public bool TryGetValue<TValue>(string parameterName, out TValue result) { throw null; }
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public partial struct Enumerator
{
@ -380,7 +380,7 @@ namespace Microsoft.AspNetCore.Components
}
}
public delegate void RenderFragment(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder);
public delegate Microsoft.AspNetCore.Components.RenderFragment RenderFragment<T>(T value);
public delegate Microsoft.AspNetCore.Components.RenderFragment RenderFragment<TValue>(TValue value);
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public readonly partial struct RenderHandle
{
@ -466,7 +466,7 @@ namespace Microsoft.AspNetCore.Components.Forms
public FieldIdentifier(object model, string fieldName) { throw null; }
public string FieldName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
public static Microsoft.AspNetCore.Components.Forms.FieldIdentifier Create<T>(System.Linq.Expressions.Expression<System.Func<T>> accessor) { throw null; }
public static Microsoft.AspNetCore.Components.Forms.FieldIdentifier Create<TField>(System.Linq.Expressions.Expression<System.Func<TField>> accessor) { throw null; }
public bool Equals(Microsoft.AspNetCore.Components.Forms.FieldIdentifier otherIdentifier) { throw null; }
public override bool Equals(object obj) { throw null; }
public override int GetHashCode() { throw null; }
@ -556,13 +556,13 @@ namespace Microsoft.AspNetCore.Components.Rendering
public void AddAttribute(int sequence, string name, System.MulticastDelegate value) { }
public void AddAttribute(int sequence, string name, object value) { }
public void AddAttribute(int sequence, string name, string value) { }
public void AddAttribute<T>(int sequence, string name, Microsoft.AspNetCore.Components.EventCallback<T> value) { }
public void AddAttribute<TArgument>(int sequence, string name, Microsoft.AspNetCore.Components.EventCallback<TArgument> value) { }
public void AddComponentReferenceCapture(int sequence, System.Action<object> componentReferenceCaptureAction) { }
public void AddContent(int sequence, Microsoft.AspNetCore.Components.MarkupString markupContent) { }
public void AddContent(int sequence, Microsoft.AspNetCore.Components.RenderFragment fragment) { }
public void AddContent(int sequence, object textContent) { }
public void AddContent(int sequence, string textContent) { }
public void AddContent<T>(int sequence, Microsoft.AspNetCore.Components.RenderFragment<T> fragment, T value) { }
public void AddContent<TValue>(int sequence, Microsoft.AspNetCore.Components.RenderFragment<TValue> fragment, TValue value) { }
public void AddElementReferenceCapture(int sequence, System.Action<Microsoft.AspNetCore.Components.ElementReference> elementReferenceCaptureAction) { }
public void AddMarkupContent(int sequence, string markupContent) { }
public void AddMultipleAttributes(int sequence, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, object>> attributes) { }

View File

@ -2,7 +2,7 @@
@implements IDisposable
@inject AuthenticationStateProvider AuthenticationStateProvider
<CascadingValue T="Task<AuthenticationState>" Value="@_currentAuthenticationStateTask" ChildContent="@ChildContent" />
<CascadingValue TValue="Task<AuthenticationState>" Value="@_currentAuthenticationStateTask" ChildContent="@ChildContent" />
@code {
private Task<AuthenticationState> _currentAuthenticationStateTask;

View File

@ -5,14 +5,13 @@ using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Rendering;
using Microsoft.AspNetCore.Components.RenderTree;
namespace Microsoft.AspNetCore.Components
{
/// <summary>
/// A component that provides a cascading value to all descendant components.
/// </summary>
public class CascadingValue<T> : ICascadingValueComponent, IComponent
public class CascadingValue<TValue> : ICascadingValueComponent, IComponent
{
private RenderHandle _renderHandle;
private HashSet<ComponentState> _subscribers; // Lazily instantiated
@ -26,7 +25,7 @@ namespace Microsoft.AspNetCore.Components
/// <summary>
/// The value to be provided.
/// </summary>
[Parameter] public T Value { get; set; }
[Parameter] public TValue Value { get; set; }
/// <summary>
/// Optionally gives a name to the provided value. Descendant components
@ -74,7 +73,7 @@ namespace Microsoft.AspNetCore.Components
{
if (parameter.Name.Equals(nameof(Value), StringComparison.OrdinalIgnoreCase))
{
Value = (T)parameter.Value;
Value = (TValue)parameter.Value;
hasSuppliedValue = true;
}
else if (parameter.Name.Equals(nameof(ChildContent), StringComparison.OrdinalIgnoreCase))
@ -86,7 +85,7 @@ namespace Microsoft.AspNetCore.Components
Name = (string)parameter.Value;
if (string.IsNullOrEmpty(Name))
{
throw new ArgumentException($"The parameter '{nameof(Name)}' for component '{nameof(CascadingValue<T>)}' does not allow null or empty values.");
throw new ArgumentException($"The parameter '{nameof(Name)}' for component '{nameof(CascadingValue<TValue>)}' does not allow null or empty values.");
}
}
else if (parameter.Name.Equals(nameof(IsFixed), StringComparison.OrdinalIgnoreCase))
@ -95,7 +94,7 @@ namespace Microsoft.AspNetCore.Components
}
else
{
throw new ArgumentException($"The component '{nameof(CascadingValue<T>)}' does not accept a parameter with the name '{parameter.Name}'.");
throw new ArgumentException($"The component '{nameof(CascadingValue<TValue>)}' does not accept a parameter with the name '{parameter.Name}'.");
}
}
@ -136,7 +135,7 @@ namespace Microsoft.AspNetCore.Components
bool ICascadingValueComponent.CanSupplyValue(Type requestedType, string requestedName)
{
if (!requestedType.IsAssignableFrom(typeof(T)))
if (!requestedType.IsAssignableFrom(typeof(TValue)))
{
return false;
}

View File

@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Components
internal readonly IHandleEvent Receiver;
/// <summary>
/// Creates the new <see cref="EventCallback{T}"/>.
/// Creates the new <see cref="EventCallback"/>.
/// </summary>
/// <param name="receiver">The event receiver.</param>
/// <param name="delegate">The delegate to bind.</param>
@ -66,73 +66,4 @@ namespace Microsoft.AspNetCore.Components
return RequiresExplicitReceiver ? (object)this : Delegate;
}
}
/// <summary>
/// A bound event handler delegate.
/// </summary>
public readonly struct EventCallback<T> : IEventCallback
{
/// <summary>
/// Gets an empty <see cref="EventCallback{T}"/>.
/// </summary>
public static readonly EventCallback<T> Empty = new EventCallback<T>(null, (Action)(() => { }));
internal readonly MulticastDelegate Delegate;
internal readonly IHandleEvent Receiver;
/// <summary>
/// Creates the new <see cref="EventCallback{T}"/>.
/// </summary>
/// <param name="receiver">The event receiver.</param>
/// <param name="delegate">The delegate to bind.</param>
public EventCallback(IHandleEvent receiver, MulticastDelegate @delegate)
{
Receiver = receiver;
Delegate = @delegate;
}
/// <summary>
/// Gets a value that indicates whether the delegate associated with this event dispatcher is non-null.
/// </summary>
public bool HasDelegate => Delegate != null;
// This is a hint to the runtime that Receiver is a different object than what
// Delegate.Target points to. This allows us to avoid boxing the command object
// when building the render tree. See logic where this is used.
internal bool RequiresExplicitReceiver => Receiver != null && !object.ReferenceEquals(Receiver, Delegate?.Target);
/// <summary>
/// Invokes the delegate associated with this binding and dispatches an event notification to the
/// appropriate component.
/// </summary>
/// <param name="arg">The argument.</param>
/// <returns>A <see cref="Task"/> which completes asynchronously once event processing has completed.</returns>
public Task InvokeAsync(T arg)
{
if (Receiver == null)
{
return EventCallbackWorkItem.InvokeAsync<T>(Delegate, arg);
}
return Receiver.HandleEventAsync(new EventCallbackWorkItem(Delegate), arg);
}
internal EventCallback AsUntyped()
{
return new EventCallback(Receiver ?? Delegate?.Target as IHandleEvent, Delegate);
}
object IEventCallback.UnpackForRenderTree()
{
return RequiresExplicitReceiver ? (object)AsUntyped() : Delegate;
}
}
// Used to understand boxed generic EventCallbacks
internal interface IEventCallback
{
bool HasDelegate { get; }
object UnpackForRenderTree();
}
}

View File

@ -105,14 +105,14 @@ namespace Microsoft.AspNetCore.Components
/// <param name="callback"></param>
/// <returns></returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public EventCallback<T> Create<T>(object receiver, EventCallback callback)
public EventCallback<TValue> Create<TValue>(object receiver, EventCallback callback)
{
if (receiver == null)
{
throw new ArgumentNullException(nameof(receiver));
}
return new EventCallback<T>(callback.Receiver, callback.Delegate);
return new EventCallback<TValue>(callback.Receiver, callback.Delegate);
}
/// <summary>
@ -122,7 +122,7 @@ namespace Microsoft.AspNetCore.Components
/// <param name="callback"></param>
/// <returns></returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public EventCallback<T> Create<T>(object receiver, EventCallback<T> callback)
public EventCallback<TValue> Create<TValue>(object receiver, EventCallback<TValue> callback)
{
if (receiver == null)
{
@ -139,14 +139,14 @@ namespace Microsoft.AspNetCore.Components
/// <param name="receiver">The event receiver.</param>
/// <param name="callback">The event callback.</param>
/// <returns>The <see cref="EventCallback"/>.</returns>
public EventCallback<T> Create<T>(object receiver, Action callback)
public EventCallback<TValue> Create<TValue>(object receiver, Action callback)
{
if (receiver == null)
{
throw new ArgumentNullException(nameof(receiver));
}
return CreateCore<T>(receiver, callback);
return CreateCore<TValue>(receiver, callback);
}
/// <summary>
@ -156,14 +156,14 @@ namespace Microsoft.AspNetCore.Components
/// <param name="receiver">The event receiver.</param>
/// <param name="callback">The event callback.</param>
/// <returns>The <see cref="EventCallback"/>.</returns>
public EventCallback<T> Create<T>(object receiver, Action<T> callback)
public EventCallback<TValue> Create<TValue>(object receiver, Action<TValue> callback)
{
if (receiver == null)
{
throw new ArgumentNullException(nameof(receiver));
}
return CreateCore<T>(receiver, callback);
return CreateCore<TValue>(receiver, callback);
}
/// <summary>
@ -173,14 +173,14 @@ namespace Microsoft.AspNetCore.Components
/// <param name="receiver">The event receiver.</param>
/// <param name="callback">The event callback.</param>
/// <returns>The <see cref="EventCallback"/>.</returns>
public EventCallback<T> Create<T>(object receiver, Func<Task> callback)
public EventCallback<TValue> Create<TValue>(object receiver, Func<Task> callback)
{
if (receiver == null)
{
throw new ArgumentNullException(nameof(receiver));
}
return CreateCore<T>(receiver, callback);
return CreateCore<TValue>(receiver, callback);
}
/// <summary>
@ -190,14 +190,14 @@ namespace Microsoft.AspNetCore.Components
/// <param name="receiver">The event receiver.</param>
/// <param name="callback">The event callback.</param>
/// <returns>The <see cref="EventCallback"/>.</returns>
public EventCallback<T> Create<T>(object receiver, Func<T, Task> callback)
public EventCallback<TValue> Create<TValue>(object receiver, Func<TValue, Task> callback)
{
if (receiver == null)
{
throw new ArgumentNullException(nameof(receiver));
}
return CreateCore<T>(receiver, callback);
return CreateCore<TValue>(receiver, callback);
}
/// <summary>
@ -209,7 +209,7 @@ namespace Microsoft.AspNetCore.Components
/// <param name="value"></param>
/// <returns></returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public EventCallback<T> CreateInferred<T>(object receiver, Action<T> callback, T value)
public EventCallback<TValue> CreateInferred<TValue>(object receiver, Action<TValue> callback, TValue value)
{
return Create(receiver, callback);
}
@ -223,7 +223,7 @@ namespace Microsoft.AspNetCore.Components
/// <param name="value"></param>
/// <returns></returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public EventCallback<T> CreateInferred<T>(object receiver, Func<T, Task> callback, T value)
public EventCallback<TValue> CreateInferred<TValue>(object receiver, Func<TValue, Task> callback, TValue value)
{
return Create(receiver, callback);
}
@ -233,9 +233,9 @@ namespace Microsoft.AspNetCore.Components
return new EventCallback(callback?.Target as IHandleEvent ?? receiver as IHandleEvent, callback);
}
private EventCallback<T> CreateCore<T>(object receiver, MulticastDelegate callback)
private EventCallback<TValue> CreateCore<TValue>(object receiver, MulticastDelegate callback)
{
return new EventCallback<T>(callback?.Target as IHandleEvent ?? receiver as IHandleEvent, callback);
return new EventCallback<TValue>(callback?.Target as IHandleEvent ?? receiver as IHandleEvent, callback);
}
}
}

View File

@ -0,0 +1,69 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Components
{
/// <summary>
/// A bound event handler delegate.
/// </summary>
public readonly struct EventCallback<TValue> : IEventCallback
{
/// <summary>
/// Gets an empty <see cref="EventCallback{TValue}"/>.
/// </summary>
public static readonly EventCallback<TValue> Empty = new EventCallback<TValue>(null, (Action)(() => { }));
internal readonly MulticastDelegate Delegate;
internal readonly IHandleEvent Receiver;
/// <summary>
/// Creates the new <see cref="EventCallback{TValue}"/>.
/// </summary>
/// <param name="receiver">The event receiver.</param>
/// <param name="delegate">The delegate to bind.</param>
public EventCallback(IHandleEvent receiver, MulticastDelegate @delegate)
{
Receiver = receiver;
Delegate = @delegate;
}
/// <summary>
/// Gets a value that indicates whether the delegate associated with this event dispatcher is non-null.
/// </summary>
public bool HasDelegate => Delegate != null;
// This is a hint to the runtime that Receiver is a different object than what
// Delegate.Target points to. This allows us to avoid boxing the command object
// when building the render tree. See logic where this is used.
internal bool RequiresExplicitReceiver => Receiver != null && !object.ReferenceEquals(Receiver, Delegate?.Target);
/// <summary>
/// Invokes the delegate associated with this binding and dispatches an event notification to the
/// appropriate component.
/// </summary>
/// <param name="arg">The argument.</param>
/// <returns>A <see cref="Task"/> which completes asynchronously once event processing has completed.</returns>
public Task InvokeAsync(TValue arg)
{
if (Receiver == null)
{
return EventCallbackWorkItem.InvokeAsync<TValue>(Delegate, arg);
}
return Receiver.HandleEventAsync(new EventCallbackWorkItem(Delegate), arg);
}
internal EventCallback AsUntyped()
{
return new EventCallback(Receiver ?? Delegate?.Target as IHandleEvent, Delegate);
}
object IEventCallback.UnpackForRenderTree()
{
return RequiresExplicitReceiver ? (object)AsUntyped() : Delegate;
}
}
}

View File

@ -16,7 +16,8 @@ namespace Microsoft.AspNetCore.Components.Forms
/// Initializes a new instance of the <see cref="FieldIdentifier"/> structure.
/// </summary>
/// <param name="accessor">An expression that identifies an object member.</param>
public static FieldIdentifier Create<T>(Expression<Func<T>> accessor)
/// <typeparam name="TField">The field <see cref="Type"/>.</typeparam>
public static FieldIdentifier Create<TField>(Expression<Func<TField>> accessor)
{
if (accessor == null)
{

View File

@ -0,0 +1,13 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Components
{
// Used to understand boxed generic EventCallbacks
internal interface IEventCallback
{
bool HasDelegate { get; }
object UnpackForRenderTree();
}
}

View File

@ -53,17 +53,17 @@ namespace Microsoft.AspNetCore.Components
/// <summary>
/// Gets the value of the parameter with the specified name.
/// </summary>
/// <typeparam name="T">The type of the value.</typeparam>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <param name="parameterName">The name of the parameter.</param>
/// <param name="result">Receives the result, if any.</param>
/// <returns>True if a matching parameter was found; false otherwise.</returns>
public bool TryGetValue<T>(string parameterName, out T result)
public bool TryGetValue<TValue>(string parameterName, out TValue result)
{
foreach (var entry in this)
{
if (string.Equals(entry.Name, parameterName))
{
result = (T)entry.Value;
result = (TValue)entry.Value;
return true;
}
}
@ -76,22 +76,22 @@ namespace Microsoft.AspNetCore.Components
/// Gets the value of the parameter with the specified name, or a default value
/// if no such parameter exists in the collection.
/// </summary>
/// <typeparam name="T">The type of the value.</typeparam>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <param name="parameterName">The name of the parameter.</param>
/// <returns>The parameter value if found; otherwise the default value for the specified type.</returns>
public T GetValueOrDefault<T>(string parameterName)
=> GetValueOrDefault<T>(parameterName, default);
public TValue GetValueOrDefault<TValue>(string parameterName)
=> GetValueOrDefault<TValue>(parameterName, default);
/// <summary>
/// Gets the value of the parameter with the specified name, or a specified default value
/// if no such parameter exists in the collection.
/// </summary>
/// <typeparam name="T">The type of the value.</typeparam>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <param name="parameterName">The name of the parameter.</param>
/// <param name="defaultValue">The default value to return if no such parameter exists in the collection.</param>
/// <returns>The parameter value if found; otherwise <paramref name="defaultValue"/>.</returns>
public T GetValueOrDefault<T>(string parameterName, T defaultValue)
=> TryGetValue<T>(parameterName, out T result) ? result : defaultValue;
public TValue GetValueOrDefault<TValue>(string parameterName, TValue defaultValue)
=> TryGetValue<TValue>(parameterName, out TValue result) ? result : defaultValue;
/// <summary>
/// Returns a dictionary populated with the contents of the <see cref="ParameterView"/>.

View File

@ -13,10 +13,10 @@ namespace Microsoft.AspNetCore.Components
public delegate void RenderFragment(RenderTreeBuilder builder);
/// <summary>
/// Represents a segment of UI content for an object of type <typeparamref name="T"/>, implemented as
/// Represents a segment of UI content for an object of type <typeparamref name="TValue"/>, implemented as
/// a function that returns a <see cref="RenderFragment"/>.
/// </summary>
/// <typeparam name="T">The type of object.</typeparam>
/// <typeparam name="TValue">The type of object.</typeparam>
/// <param name="value">The value used to build the content.</param>
public delegate RenderFragment RenderFragment<T>(T value);
public delegate RenderFragment RenderFragment<TValue>(TValue value);
}

View File

@ -116,7 +116,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
/// <param name="sequence">An integer that represents the position of the instruction in the source code.</param>
/// <param name="fragment">Content to append.</param>
/// <param name="value">The value used by <paramref name="fragment"/>.</param>
public void AddContent<T>(int sequence, RenderFragment<T> fragment, T value)
public void AddContent<TValue>(int sequence, RenderFragment<TValue> fragment, TValue value)
{
if (fragment != null)
{
@ -281,7 +281,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
/// This method is provided for infrastructure purposes, and is used to support generated code
/// that uses <see cref="EventCallbackFactory"/>.
/// </remarks>
public void AddAttribute<T>(int sequence, string name, EventCallback<T> value)
public void AddAttribute<TArgument>(int sequence, string name, EventCallback<TArgument> value)
{
AssertCanAddAttribute();
if (_lastNonAttributeFrameType == RenderTreeFrameType.Component)

View File

@ -308,25 +308,25 @@ namespace Microsoft.AspNetCore.Components.Forms
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { }
protected override void OnParametersSet() { }
}
public abstract partial class InputBase<T> : Microsoft.AspNetCore.Components.ComponentBase
public abstract partial class InputBase<TValue> : Microsoft.AspNetCore.Components.ComponentBase
{
protected InputBase() { }
[Microsoft.AspNetCore.Components.ParameterAttribute(CaptureUnmatchedValues=true)]
public System.Collections.Generic.IReadOnlyDictionary<string, object> AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
protected string CssClass { get { throw null; } }
protected T CurrentValue { get { throw null; } set { } }
protected TValue CurrentValue { get { throw null; } set { } }
protected string CurrentValueAsString { get { throw null; } set { } }
protected Microsoft.AspNetCore.Components.Forms.EditContext EditContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
protected Microsoft.AspNetCore.Components.Forms.FieldIdentifier FieldIdentifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
[Microsoft.AspNetCore.Components.ParameterAttribute]
public T Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
public TValue Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
[Microsoft.AspNetCore.Components.ParameterAttribute]
public Microsoft.AspNetCore.Components.EventCallback<T> ValueChanged { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
public Microsoft.AspNetCore.Components.EventCallback<TValue> ValueChanged { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
[Microsoft.AspNetCore.Components.ParameterAttribute]
public System.Linq.Expressions.Expression<System.Func<T>> ValueExpression { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
protected virtual string FormatValueAsString(T value) { throw null; }
public System.Linq.Expressions.Expression<System.Func<TValue>> ValueExpression { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
protected virtual string FormatValueAsString(TValue value) { throw null; }
public override System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters) { throw null; }
protected abstract bool TryParseValueFromString(string value, out T result, out string validationErrorMessage);
protected abstract bool TryParseValueFromString(string value, out TValue result, out string validationErrorMessage);
}
public partial class InputCheckbox : Microsoft.AspNetCore.Components.Forms.InputBase<bool>
{
@ -334,31 +334,31 @@ namespace Microsoft.AspNetCore.Components.Forms
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { }
protected override bool TryParseValueFromString(string value, out bool result, out string validationErrorMessage) { throw null; }
}
public partial class InputDate<T> : Microsoft.AspNetCore.Components.Forms.InputBase<T>
public partial class InputDate<TValue> : Microsoft.AspNetCore.Components.Forms.InputBase<TValue>
{
public InputDate() { }
[Microsoft.AspNetCore.Components.ParameterAttribute]
public string ParsingErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { }
protected override string FormatValueAsString(T value) { throw null; }
protected override bool TryParseValueFromString(string value, out T result, out string validationErrorMessage) { throw null; }
protected override string FormatValueAsString(TValue value) { throw null; }
protected override bool TryParseValueFromString(string value, out TValue result, out string validationErrorMessage) { throw null; }
}
public partial class InputNumber<T> : Microsoft.AspNetCore.Components.Forms.InputBase<T>
public partial class InputNumber<TValue> : Microsoft.AspNetCore.Components.Forms.InputBase<TValue>
{
public InputNumber() { }
[Microsoft.AspNetCore.Components.ParameterAttribute]
public string ParsingErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { }
protected override string FormatValueAsString(T value) { throw null; }
protected override bool TryParseValueFromString(string value, out T result, out string validationErrorMessage) { throw null; }
protected override string FormatValueAsString(TValue value) { throw null; }
protected override bool TryParseValueFromString(string value, out TValue result, out string validationErrorMessage) { throw null; }
}
public partial class InputSelect<T> : Microsoft.AspNetCore.Components.Forms.InputBase<T>
public partial class InputSelect<TValue> : Microsoft.AspNetCore.Components.Forms.InputBase<TValue>
{
public InputSelect() { }
[Microsoft.AspNetCore.Components.ParameterAttribute]
public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { }
protected override bool TryParseValueFromString(string value, out T result, out string validationErrorMessage) { throw null; }
protected override bool TryParseValueFromString(string value, out TValue result, out string validationErrorMessage) { throw null; }
}
public partial class InputText : Microsoft.AspNetCore.Components.Forms.InputBase<string>
{
@ -372,13 +372,13 @@ namespace Microsoft.AspNetCore.Components.Forms
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { }
protected override bool TryParseValueFromString(string value, out string result, out string validationErrorMessage) { throw null; }
}
public partial class ValidationMessage<T> : Microsoft.AspNetCore.Components.ComponentBase, System.IDisposable
public partial class ValidationMessage<TValue> : Microsoft.AspNetCore.Components.ComponentBase, System.IDisposable
{
public ValidationMessage() { }
[Microsoft.AspNetCore.Components.ParameterAttribute(CaptureUnmatchedValues=true)]
public System.Collections.Generic.IReadOnlyDictionary<string, object> AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
[Microsoft.AspNetCore.Components.ParameterAttribute]
public System.Linq.Expressions.Expression<System.Func<T>> For { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
public System.Linq.Expressions.Expression<System.Func<TValue>> For { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { }
protected virtual void Dispose(bool disposing) { }
protected override void OnParametersSet() { }

View File

@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Components.Forms
/// integrates with an <see cref="Forms.EditContext"/>, which must be supplied
/// as a cascading parameter.
/// </summary>
public abstract class InputBase<T> : ComponentBase
public abstract class InputBase<TValue> : ComponentBase
{
private bool _previousParsingAttemptFailed;
private ValidationMessageStore _parsingValidationMessages;
@ -32,20 +32,20 @@ namespace Microsoft.AspNetCore.Components.Forms
/// <example>
/// @bind-Value="model.PropertyName"
/// </example>
[Parameter] public T Value { get; set; }
[Parameter] public TValue Value { get; set; }
/// <summary>
/// Gets or sets a callback that updates the bound value.
/// </summary>
[Parameter] public EventCallback<T> ValueChanged { get; set; }
[Parameter] public EventCallback<TValue> ValueChanged { get; set; }
/// <summary>
/// Gets or sets an expression that identifies the bound value.
/// </summary>
[Parameter] public Expression<Func<T>> ValueExpression { get; set; }
[Parameter] public Expression<Func<TValue>> ValueExpression { get; set; }
/// <summary>
/// Gets the associated <see cref="Microsoft.AspNetCore.Components.Forms.EditContext"/>.
/// Gets the associated <see cref="Forms.EditContext"/>.
/// </summary>
protected EditContext EditContext { get; set; }
@ -57,12 +57,12 @@ namespace Microsoft.AspNetCore.Components.Forms
/// <summary>
/// Gets or sets the current value of the input.
/// </summary>
protected T CurrentValue
protected TValue CurrentValue
{
get => Value;
set
{
var hasChanged = !EqualityComparer<T>.Default.Equals(value, Value);
var hasChanged = !EqualityComparer<TValue>.Default.Equals(value, Value);
if (hasChanged)
{
Value = value;
@ -126,18 +126,18 @@ namespace Microsoft.AspNetCore.Components.Forms
/// </summary>
/// <param name="value">The value to format.</param>
/// <returns>A string representation of the value.</returns>
protected virtual string FormatValueAsString(T value)
protected virtual string FormatValueAsString(TValue value)
=> value?.ToString();
/// <summary>
/// Parses a string to create an instance of <typeparamref name="T"/>. Derived classes can override this to change how
/// Parses a string to create an instance of <typeparamref name="TValue"/>. Derived classes can override this to change how
/// <see cref="CurrentValueAsString"/> interprets incoming values.
/// </summary>
/// <param name="value">The string value to be parsed.</param>
/// <param name="result">An instance of <typeparamref name="T"/>.</param>
/// <param name="result">An instance of <typeparamref name="TValue"/>.</param>
/// <param name="validationErrorMessage">If the value could not be parsed, provides a validation error message.</param>
/// <returns>True if the value could be parsed; otherwise false.</returns>
protected abstract bool TryParseValueFromString(string value, out T result, out string validationErrorMessage);
protected abstract bool TryParseValueFromString(string value, out TValue result, out string validationErrorMessage);
/// <summary>
/// Gets a string that indicates the status of the field being edited. This will include
@ -192,7 +192,7 @@ namespace Microsoft.AspNetCore.Components.Forms
EditContext = CascadedEditContext;
FieldIdentifier = FieldIdentifier.Create(ValueExpression);
_nullableUnderlyingType = Nullable.GetUnderlyingType(typeof(T));
_nullableUnderlyingType = Nullable.GetUnderlyingType(typeof(TValue));
}
else if (CascadedEditContext != EditContext)
{

View File

@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Components.Forms
/// An input component for editing date values.
/// Supported types are <see cref="DateTime"/> and <see cref="DateTimeOffset"/>.
/// </summary>
public class InputDate<T> : InputBase<T>
public class InputDate<TValue> : InputBase<TValue>
{
private const string DateFormat = "yyyy-MM-dd"; // Compatible with HTML date inputs
@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.Components.Forms
}
/// <inheritdoc />
protected override string FormatValueAsString(T value)
protected override string FormatValueAsString(TValue value)
{
switch (value)
{
@ -47,11 +47,11 @@ namespace Microsoft.AspNetCore.Components.Forms
}
/// <inheritdoc />
protected override bool TryParseValueFromString(string value, out T result, out string validationErrorMessage)
protected override bool TryParseValueFromString(string value, out TValue result, out string validationErrorMessage)
{
// Unwrap nullable types. We don't have to deal with receiving empty values for nullable
// types here, because the underlying InputBase already covers that.
var targetType = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);
var targetType = Nullable.GetUnderlyingType(typeof(TValue)) ?? typeof(TValue);
bool success;
if (targetType == typeof(DateTime))
@ -79,12 +79,12 @@ namespace Microsoft.AspNetCore.Components.Forms
}
}
static bool TryParseDateTime(string value, out T result)
static bool TryParseDateTime(string value, out TValue result)
{
var success = BindConverter.TryConvertToDateTime(value, CultureInfo.InvariantCulture, DateFormat, out var parsedValue);
if (success)
{
result = (T)(object)parsedValue;
result = (TValue)(object)parsedValue;
return true;
}
else
@ -94,12 +94,12 @@ namespace Microsoft.AspNetCore.Components.Forms
}
}
static bool TryParseDateTimeOffset(string value, out T result)
static bool TryParseDateTimeOffset(string value, out TValue result)
{
var success = BindConverter.TryConvertToDateTimeOffset(value, CultureInfo.InvariantCulture, DateFormat, out var parsedValue);
if (success)
{
result = (T)(object)parsedValue;
result = (TValue)(object)parsedValue;
return true;
}
else

View File

@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Components.Forms
/// An input component for editing numeric values.
/// Supported numeric types are <see cref="int"/>, <see cref="long"/>, <see cref="float"/>, <see cref="double"/>, <see cref="decimal"/>.
/// </summary>
public class InputNumber<T> : InputBase<T>
public class InputNumber<TValue> : InputBase<TValue>
{
private static string _stepAttributeValue; // Null by default, so only allows whole numbers as per HTML spec
@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Components.Forms
{
// Unwrap Nullable<T>, because InputBase already deals with the Nullable aspect
// of it for us. We will only get asked to parse the T for nonempty inputs.
var targetType = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);
var targetType = Nullable.GetUnderlyingType(typeof(TValue)) ?? typeof(TValue);
if (targetType == typeof(int) ||
targetType == typeof(float) ||
targetType == typeof(double) ||
@ -52,9 +52,9 @@ namespace Microsoft.AspNetCore.Components.Forms
}
/// <inheritdoc />
protected override bool TryParseValueFromString(string value, out T result, out string validationErrorMessage)
protected override bool TryParseValueFromString(string value, out TValue result, out string validationErrorMessage)
{
if (BindConverter.TryConvertTo<T>(value, CultureInfo.InvariantCulture, out result))
if (BindConverter.TryConvertTo<TValue>(value, CultureInfo.InvariantCulture, out result))
{
validationErrorMessage = null;
return true;
@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Components.Forms
/// </summary>
/// <param name="value">The value to format.</param>
/// <returns>A string representation of the value.</returns>
protected override string FormatValueAsString(T value)
protected override string FormatValueAsString(TValue value)
{
// Avoiding a cast to IFormattable to avoid boxing.
switch (value)

View File

@ -10,7 +10,7 @@ namespace Microsoft.AspNetCore.Components.Forms
/// <summary>
/// A dropdown selection component.
/// </summary>
public class InputSelect<T> : InputBase<T>
public class InputSelect<TValue> : InputBase<TValue>
{
/// <summary>
/// Gets or sets the child content to be rendering inside the select element.
@ -30,17 +30,17 @@ namespace Microsoft.AspNetCore.Components.Forms
}
/// <inheritdoc />
protected override bool TryParseValueFromString(string value, out T result, out string validationErrorMessage)
protected override bool TryParseValueFromString(string value, out TValue result, out string validationErrorMessage)
{
if (typeof(T) == typeof(string))
if (typeof(TValue) == typeof(string))
{
result = (T)(object)value;
result = (TValue)(object)value;
validationErrorMessage = null;
return true;
}
else if (typeof(T).IsEnum)
else if (typeof(TValue).IsEnum)
{
var success = BindConverter.TryConvertTo<T>(value, CultureInfo.CurrentCulture, out var parsedValue);
var success = BindConverter.TryConvertTo<TValue>(value, CultureInfo.CurrentCulture, out var parsedValue);
if (success)
{
result = parsedValue;
@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.Components.Forms
}
}
throw new InvalidOperationException($"{GetType()} does not support the type '{typeof(T)}'.");
throw new InvalidOperationException($"{GetType()} does not support the type '{typeof(TValue)}'.");
}
}
}

View File

@ -11,10 +11,10 @@ namespace Microsoft.AspNetCore.Components.Forms
/// <summary>
/// Displays a list of validation messages for a specified field within a cascaded <see cref="EditContext"/>.
/// </summary>
public class ValidationMessage<T> : ComponentBase, IDisposable
public class ValidationMessage<TValue> : ComponentBase, IDisposable
{
private EditContext _previousEditContext;
private Expression<Func<T>> _previousFieldAccessor;
private Expression<Func<TValue>> _previousFieldAccessor;
private readonly EventHandler<ValidationStateChangedEventArgs> _validationStateChangedHandler;
private FieldIdentifier _fieldIdentifier;
@ -28,10 +28,10 @@ namespace Microsoft.AspNetCore.Components.Forms
/// <summary>
/// Specifies the field for which validation messages should be displayed.
/// </summary>
[Parameter] public Expression<Func<T>> For { get; set; }
[Parameter] public Expression<Func<TValue>> For { get; set; }
/// <summary>`
/// Constructs an instance of <see cref="ValidationMessage{T}"/>.
/// Constructs an instance of <see cref="ValidationMessage{TValue}"/>.
/// </summary>
public ValidationMessage()
{

View File

@ -80,7 +80,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
await ValidateClientKeepsWorking(Client, batches);
}
[Fact]
[Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/12940")]
public async Task CannotInvokeJSInvokableMethodsWithWrongNumberOfArguments()
{
// Arrange
@ -259,7 +259,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
await ValidateClientKeepsWorking(Client, batches);
}
[Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/12962")]
[Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/12940")]
public async Task LogsJSInteropCompletionsCallbacksAndContinuesWorkingInAllSituations()
{
// Arrange
@ -445,7 +445,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests
await ValidateClientKeepsWorking(Client, batches);
}
[Fact]
[Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/12940")]
public async Task DispatchingEventsWithInvalidEventHandlerId()
{
// Arrange