¿Por qué necesita una "colección y una enumeración"? ¿Cuál es el problema con el uso de una enumeración Bit Field con el atributo "Flags" para almacenar qué "Certs" tiene una "Persona"? Esto es en realidad una versión mucho más limpio de la opción 1.
por su comentario, aquí es un ejemplo muy trivial de lo que estoy hablando:
class Person
{
public string Name;
public Certifications Certifications;
}
[Flags]
enum Certifications : int
{
A = 1,
B = 2,
C = 4,
D = 8,
E = 16,
F = 32,
G = 64,
H = 128,
I = 256
};
static void Main()
{
Person a = new Person() { Name = "rob", Certifications = Certifications.A | Certifications.D | Certifications.G };
Person b = new Person() { Name = "jeb", Certifications = Certifications.B | Certifications.C | Certifications.I };
// Easy way using [Flags] ToString() override.
DisplayPerson(a);
DisplayPerson(b);
Console.WriteLine();
// Traditional Way
DisplayPersonInfo(a);
DisplayPersonInfo(b);
}
static IEnumerable<string> GetCerts(Person person)
{
foreach(Certifications cert in Enum.GetValues(typeof(Certifications)))
{
if(PersonHasCert(person, cert))
yield return (Enum.GetName(typeof(Certifications), cert));
}
}
static bool PersonHasCert(Person person, Certifications cert)
{
return ((cert & person.Certifications) == cert);
}
static void DisplayPersonInfo(Person p)
{
Console.WriteLine
(
String.Format
(
"Name: {0}, Certifications: {1}",
p.Name,
String.Join(", ", GetCerts(p))
)
);
}
static void DisplayPerson(Person p)
{
Console.WriteLine
(
String.Format
(
"Name: {0}, Certifications: {1}",
p.Name,
p.Certifications
)
);
}
Salida:
Nombre: rob, Certificados: A, D, G
Nombre: jeb, certificaciones: B, C, I
Nombre: robo, Certificaciones: A, D, G
Nombre: jeb, Certificaciones: B, C, I
la mencionada "[Banderas]" atributo de ayuda al compilador sé lo que estás utilizando esta estructura de datos para y mostrar los valores que contiene (utilizando el método ToString() en un "Enum" con el atributo, por lo que no tiene que iterar el Enum y hacer una prueba de bits para cada valor cuando desea mostrar todo el valores).
¿Cuáles son sus otras reservas sobre el uso de este enfoque? Parece ajustarse exactamente a lo que quieres lograr de manera muy eficiente y limpia.
this es un artículo bastante bueno sobre el tema.
Edición 2:
Código de ejemplo actualizado para incluir programa de ejemplo completo con las dos maneras de conseguir esta funcionalidad y algunos métodos de ayuda que usted debe ser capaz de utilizar en su aplicación.
Este fue mi instinto, sin embargo, me resultó más difícil implementar b/c Tengo un formulario con casillas de verificación, por lo que Person.HasCertL1 = CertL1Box.Checked fue más limpio que si Cert1Box.Checked Then Person.Certs.Add (Certs.CertL1) , especialmente cuando intentas eliminarlos. Voy a utilizar tus sugerencias de todos modos, ¡nunca se sabe cuándo querrás reutilizar algo! :) –
Las alegrías del diseño de software; nunca podrá escribir código que esté completamente desacoplado de sus dependencias y dependientes. Lo que puede hacer es enfocarse en ciertas situaciones en las que el código podría cambiar y asegurarse de que el código externo requiera un mínimo o ningún cambio en esas situaciones. – KeithS