-1

Question:

Is there a work around to be able to use generics in the constructor of a class that inherits from a class that doesn't have generic types defined?


Explanation:

I am creating a new custom attribute inheriting from the ValidationAttribute class. I want to use generic types in the constructor as seen below:

DateValidationAttribute : ValidationAttribute {

   public void DateValidationAttribute <TData>(Expression<Func<TData, DateTime?>> property){ ... }

}

However, this doesn't seem to be allowed as the TData and TProperty generic types aren't recognized as generics. In addition I cannot define the generics in the class definition as it inherits from the ValidationAttribute class. The error I get is that TData and TProperty is not defined.


Goal:

The goal of passing and expression down to have a strongly typed way of passing attribute names. I am writing this attribute to compare two properties of a class. The implementation below is what it looks like. Beneath that is how I want the implementation to look like:

Current:

public DateTime? ToDate { get; set; }

[DateValidation("ToDate")]
public DateTime? FromDate { get; set; }

Goal:

public DateTime? ToDate { get; set; }

[DateValidation(prop => prop.ToDate)]
public DateTime? FromDate { get; set; }    
Cornel
  • 72
  • 1
  • 7
  • What **exactly** do you mean by "child of class"? – Lasse V. Karlsen Feb 10 '19 at 23:11
  • 3
    Also know that you cannot make a constructor generic, you will have to make the type generic. Could you take a step back and tell us what you're trying to accomplish, instead of how you tried to accomplish it? – Lasse V. Karlsen Feb 10 '19 at 23:12
  • @Lasse Vågsæther Karlsen I reworked the question to better explain points you were unclear about and added the objective of what I am trying to accomplish. – Cornel Feb 10 '19 at 23:23
  • 2
    Your goal will not work because the types that can be specified in an attribute usage [are limited](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/attributes#attribute-parameter-types), and `Expression` is not one of those types. – Joe Sewell Feb 10 '19 at 23:29
  • Possible duplicate of [use decimal values as attribute params in c#?](https://stackoverflow.com/questions/507528/use-decimal-values-as-attribute-params-in-c) – Derviş Kayımbaşıoğlu Feb 10 '19 at 23:31

1 Answers1

2

The non-support for generics in attributes is the least of your problems. Attributes can only have a specific subset of types (primitives, enums, String, Type and single-dimensional arrays) as constructor arguments, not lambdas. So even if you could use generics you could not do what you're trying to do.

Consider using a string as constructor parameter and using nameof(), e.g.:

[DateValidation(nameof(ToDate))]

This approach keeps the names in sync with the real property name and thus you get the safety you want when refactoring etc.

Lucero
  • 59,176
  • 9
  • 122
  • 152
  • Here's the list of types you can use in attributes: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/attributes#attribute-parameter-types – Joe Sewell Feb 10 '19 at 23:31