using System;
using System.Collections.Concurrent;
using System.Reflection;
namespace Swan.Reflection {
///
/// Represents a Method Info Cache.
///
public class MethodInfoCache : ConcurrentDictionary {
///
/// Retrieves the properties stored for the specified type.
/// If the properties are not available, it calls the factory method to retrieve them
/// and returns them as an array of PropertyInfo.
///
/// The type of type.
/// The name.
/// The alias.
/// The types.
///
/// The cached MethodInfo.
///
/// name
/// or
/// factory.
public MethodInfo Retrieve(String name, String alias, params Type[] types) => this.Retrieve(typeof(T), name, alias, types);
///
/// Retrieves the specified name.
///
/// The type of type.
/// The name.
/// The types.
///
/// The cached MethodInfo.
///
public MethodInfo Retrieve(String name, params Type[] types) => this.Retrieve(typeof(T), name, name, types);
///
/// Retrieves the specified type.
///
/// The type.
/// The name.
/// The types.
///
/// An array of the properties stored for the specified type.
///
public MethodInfo Retrieve(Type type, String name, params Type[] types) => this.Retrieve(type, name, name, types);
///
/// Retrieves the specified type.
///
/// The type.
/// The name.
/// The alias.
/// The types.
///
/// The cached MethodInfo.
///
public MethodInfo Retrieve(Type type, String name, String alias, params Type[] types) {
if(type == null) {
throw new ArgumentNullException(nameof(type));
}
if(alias == null) {
throw new ArgumentNullException(nameof(alias));
}
if(name == null) {
throw new ArgumentNullException(nameof(name));
}
return this.GetOrAdd(alias, x => type.GetMethod(name, types ?? Array.Empty()));
}
///
/// Retrieves the specified name.
///
/// The type of type.
/// The name.
///
/// The cached MethodInfo.
///
public MethodInfo Retrieve(String name) => this.Retrieve(typeof(T), name);
///
/// Retrieves the specified type.
///
/// The type.
/// The name.
///
/// The cached MethodInfo.
///
///
/// type
/// or
/// name.
///
public MethodInfo Retrieve(Type type, String name) {
if(type == null) {
throw new ArgumentNullException(nameof(type));
}
if(name == null) {
throw new ArgumentNullException(nameof(name));
}
return this.GetOrAdd(name, type.GetMethod);
}
}
}