Abstraction for duplicated code [Answered]

DDuke8/16/2022
Hi, I have the following classes:
public static class IdentityState
{
    public const string Active = "Active";
    public const string Locked = "Locked";
    public const string Pending = "Pending";
    
    public static readonly string[] All = {Active, Locked, Pending};
    public static bool IsValid(string state) => All.Contains(state);
}

public static class CredentialTypes
{
    public const string Password = "password";
    public const string Oidc = "oidc";
    public const string Totp = "totp";
    public const string LookupSecret = "lookup_secret";
    public const string MagicLink = "magic_link";
    
    public static readonly string[] All = { Password, Oidc, Totp, LookupSecret, MagicLink };
    public static bool IsValid(string type) => All.Contains(type);
}


How can I abstract away the common methods/props (All and IsValid())
DDuke8/16/2022
My end goal is to make a fluentvalidation extension method that can automatically validate these string enums, usage would be something like RuleFor(x => x.SomeString).OneOf<IdentityState>()
DDuke8/16/2022
SSusko38/16/2022
This can work if the classes are not static, and if you do
-public static readonly string[] All = { Password, Oidc, Totp, LookupSecret, MagicLink };
+public string[] All { get; } = { Password, Oidc, Totp, LookupSecret, MagicLink };
SSusko38/16/2022
but then you'd have to have
RuleFor(x => x.SomeString).OneOf(new IdentityState())
SSusko38/16/2022
not sure....
EEro8/16/2022
you need .NET 7 for this
EEro8/16/2022
interface IInterface
{
    abstract static string[] All { get; }
    abstract static bool IsValid(string value);
}

class Class : IInterface
{
    public static string[] All { get; } = { "foo", "bar", "baz" };
    public static bool IsValid(string value) => All.Contains(value);
}
EEro8/16/2022
static classes still can't implement interfaces of course
Aamio8/16/2022
Do you need All for something? What? Otherwise maybe something like an IValidateable/<T>
DDuke8/16/2022
I'm using All for the is valid method
DDuke8/16/2022
Would there be a better way?
DDuke8/16/2022
Can you still access the static members of a non static class?
EEro8/16/2022
Sure
DDuke8/16/2022
This feels like a weird usage
Aamio8/16/2022
What you care about is being able to validate stuff. If "All" is only there for that purpose, it's an implementation detail and doesn't need to be exposed at all.
DDuke8/16/2022
Hmm okay
DDuke8/16/2022
So it can be private I guess
DDuke8/16/2022
But it doesn't have anything to do with the abstraction right
Aamio8/16/2022
It kind of is your whole abstraction. But maybe you should be using something like fluentvalidation instead? Either way, All doesn't need to be part of your "interface"
DDuke8/16/2022
I am using fluentvalidation yes
DDuke8/16/2022
I want to use the class like a string enum
DDuke8/16/2022
Maybe there's a better approach to that problem?
DDuke8/16/2022
!close
AAccord8/16/2022
✅ This post has been marked as answered!