/// <summary> /// Gets the required cast statement, if any, to use the value of a property when constructing the model. /// </summary> /// <param name="modelType">The model type.</param> /// <param name="propertyOfConcern">The property of concern.</param> /// <returns> /// The cast statement, if any is required. /// </returns> public static string CastIfConstructorParameterIsOfDifferentType( this ModelType modelType, PropertyOfConcern propertyOfConcern) { string result; var propertyName = propertyOfConcern.Name; if (modelType.PropertyNameToConstructorParameterTypeMap.ContainsKey(propertyName)) { var constructorParameterType = modelType.PropertyNameToConstructorParameterTypeMap[propertyName]; var propertyType = propertyOfConcern.PropertyType; result = propertyType != constructorParameterType ? Invariant($"({constructorParameterType.ToStringReadable()})") : string.Empty; } else { result = string.Empty; } return(result); }
private static string GenerateHashCodeMethodCodeForProperty( this PropertyOfConcern propertyOfConcern) { new { propertyOfConcern }.AsArg().Must().NotBeNull(); var result = Invariant($"Hash(this.{propertyOfConcern.Name})"); return(result); }
private static string GenerateEqualityLogicCodeForProperty( this PropertyOfConcern propertyOfConcern) { new { propertyOfConcern }.AsArg().Must().NotBeNull(); var result = (propertyOfConcern.PropertyType == typeof(string)) ? Invariant($"this.{propertyOfConcern.Name}.IsEqualTo(other.{propertyOfConcern.Name}, StringComparer.Ordinal)") : Invariant($"this.{propertyOfConcern.Name}.IsEqualTo(other.{propertyOfConcern.Name})"); return(result); }
/// <summary> /// Determines if the model's constructor is missing a parameter that corresponds /// to the specified property of concern. /// </summary> /// <remarks> /// This occurs when a base class property isn't a constructor parameter (so the concrete class is passing a compile-time constant to the base class). /// </remarks> /// <param name="modelType">The model type.</param> /// <param name="propertyOfConcern">The property of concern.</param> /// <returns> /// true if the model has a public, non-default constructor that is missing a parameter that corresponds to the specified property. /// </returns> public static bool IsMissingCorrespondingConstructorParameter( this ModelType modelType, PropertyOfConcern propertyOfConcern) { new { modelType }.AsArg().Must().NotBeNull(); new { propertyOfConcern }.AsArg().Must().NotBeNull(); var result = (modelType.HierarchyKind == HierarchyKind.ConcreteInherited) && (!modelType.Constructor.IsDefaultConstructor()) && (!modelType.Constructor.GetParameters().Select(_ => _.Name).Contains(propertyOfConcern.Name, StringComparer.OrdinalIgnoreCase)); return(result); }
/// <summary> /// Converts a property to it's corresponding parameter name /// in constructors and other methods. /// </summary> /// <param name="propertyOfConcern">The property of concern.</param> /// <param name="forXmlDoc">A value indicating whether the parameter name will be used used in XML doc.</param> /// <returns> /// The parameter name. /// </returns> public static string ToParameterName( this PropertyOfConcern propertyOfConcern, bool forXmlDoc = false) { new { propertyOfConcern }.AsArg().Must().NotBeNull(); var result = propertyOfConcern.Name.ToLowerFirstCharacter(CultureInfo.InvariantCulture); if (!forXmlDoc) { using (var codeProvider = new CSharpCodeProvider()) { if (!codeProvider.IsValidIdentifier(result)) { result = "@" + result; } } } return(result); }
private static string GenerateToStringForProperty( this PropertyOfConcern propertyOfConcern, bool useSystemUnderTest) { var name = propertyOfConcern.Name; var type = propertyOfConcern.PropertyType; var takesFormatProviderType = type; // an open nullable type will just result in the generic parameter as it's underlying type, // which is why we purposefully only check for closed nullable types here. if (type.IsClosedNullableType()) { takesFormatProviderType = Nullable.GetUnderlyingType(type); } // ReSharper disable once PossibleNullReferenceException var takesFormatProvider = takesFormatProviderType.GetMethods().Where(_ => _.Name == "ToString").Where(_ => !_.IsObsolete()).Where(_ => _.GetParameters().Length == 1).Any(_ => typeof(IFormatProvider).IsAssignableFrom(_.GetParameters().Single().ParameterType)); var result = name + " = {" + (useSystemUnderTest ? "systemUnderTest" : "this") + "." + name + (type.IsTypeAssignableToNull() ? "?" : string.Empty) + ".ToString(" + (takesFormatProvider ? "CultureInfo.InvariantCulture" : string.Empty) + ") ?? \"<null>\"}"; return(result); }