2009-04-08 6 views
6

Estoy tratando de agregar una restricción a un método genérico para que compruebe los ValueTypes, Strings o tipos de valores Nullable.Restricción genérica a ValueTypes, Cadenas y Nullable de ValueTypes

El problema es que:

  • tipos de valor son puntales
  • cuerdas están los tipos de referencia inmutables
  • anulable son los tipos de valor, pero no serán aceptadas en una "S donde: struct" restricción de tipo .

Entonces, ¿alguien sabe si hay una forma en que puedo aceptar estos y solo estos tipos en una restricción genérica?

El problema es que estoy tratando de aceptar un parámetro Expression<Func<T, S> que representará una propiedad de estos tipos para un objeto dado.

La funcionalidad sería algo así como lo siguiente (tenga en cuenta que el código no tiene ningún sentido y es simplemente algo rápido para tener una idea de lo que estoy buscando):

public class Person 
{ 
    public string Name {get; set;} 
    public DateTime? DOB {get; set;} 
    public int NumberOfChildren {get; set;} 
    public Car CurrentCar {get; set;} 
} 

--- 

internal void MyGenericMethod<T, S>(T myObject, Expression<Func<T, S> property){...} 

Person myPerson = new Person(); 
MyGenericMethod(myPerson, p => p.Name); //S would be a string 
MyGenericMethod(myPerson, p => p.DOB); //S would be a DateTime? 
MyGenericMethod(myPerson, p => p.NumberOfChildren); //S would be a struct 

Las tres llamadas por encima de todos deben ser aceptados, pero no el siguiente:

MyGenericMethod(myPerson, p => p.CurrentCar); //S would be a class and shouldn't compile 

Gracias de antemano

ACTUALIZACIÓN: Gracias Anton y Marc. MyGenericMethod tiene 4 firmas diferentes que aceptan parámetros adicionales, es por eso que no me gusta la idea de crear 3 diferentes (struct, nullable, string) para cada uno de los 4 existentes ... ¡eso sería una pesadilla para mantener!

Respuesta

7

La única cosa que puedo llegar a es un conjunto de tres funciones (sans Expression<> cosas):

MyGenericFunction<T>(T t) 
    where T : struct 

MyGenericFunction<T>(T? t) 
    where T : struct 

MyGenericFunction(string s) 

ACTUALIZACIÓN Dado que hay varias sobrecargas de un método, puedo sugerir:

class Holder 
{ 
    private object value; 

    public Holder(object value) 
    { 
     this.value = value; 
    } 

    public static implicit operator Holder(DateTime dt) 
    { 
     return new Holder(dt); 
    } 

    public static implicit operator Holder(string s) 
    { 
     return new Holder(s); 
    } 

    // Implicit conversion operators from primitive types 
} 

De este modo se convierte en el método de

MyGenericMethod(Holder h); 

Todavía es muy engorroso, pero sin embargo podría funcionar.

+0

Puede tener sentido definir 'struct Holder' en su lugar. Luego se convierte en "azúcar sintáctico" en tiempo de compilación, cuyo propósito es especificar qué es y qué no es legal. Pero el resultado del tiempo de ejecución sería eficiente: elimina la asignación/recolección de basura necesaria para una clase. – ToolmakerSteve

Cuestiones relacionadas