2011-04-04 21 views
11

quiero decir:¿Cómo puedo configurar un parámetro para DateTime.MaxValue en C#?

public void Problem(DateTime optional = DateTime.MaxValue) 
{ 
} 

Pero el compilador se queja de que DateTime.MaxValue no es una constante de tiempo de compilación.

DateTime.MinValue es fácil, sólo tiene que utilizar por defecto (DateTime)

ver también "How do I default a parameter to Guid.Empty in C#?"

no deseo utilizar la sobrecarga de métodos, como el método que estoy tratando de domesticar tiene 101 parámetros!

+2

@Sam Holder Pero, ¿cómo un OP con 8.5k termina con 101 parámetros en su método? Nunca me había ocurrido eso. Realmente me gustaría saber por qué este parece ser el mejor diseño. Parece que hay un nivel insano de acoplamiento allí. Intuitivamente, me sorprendería si obtienes buenas "métricas de código" para un método como ese. –

+0

@Sam Holder para citar a Jerry Seinfeld: "Si tienes una camiseta con manchas de sangre por todos lados, tal vez la lavandería no sea tu mayor problema en este momento". El problema de DateTime parece periférico al problema del parámetro. –

+2

@Simen, 101 parámetros pueden ocurrir de varias maneras. Sistemas heredados; equipos de desarrolladores que amplían el comportamiento debido a la falta de tiempo para refactorizar (incurriendo así en deuda técnica); y por supuesto, como es este caso, sarcasmo masivo. Además, ¿qué te hace pensar que los 101 parámetros son suyos? –

Respuesta

9

que sería sustituir esto para algo como:

public void Problem(DateTime? optional = null) 
{ 
    DateTime dateTime = optional != null ? optional.Value : DateTime.MaxValue; 
    // Now use dateTime 
} 
+1

Esto parece ser la opción menos mala, dado que no puedo reescribir la base de código. –

+7

@IanRingrose Es posible que también desee escribirlo utilizando [el operador nulo-coalescente] (http://msdn.microsoft.com/en-us/library/ms173224.aspx), es decir: 'DateTime dateTime = optional ?? DateTime.MaxValue; ' –

3

Se pueden definir varias funciones:

public void Problem() 
{ 
    Problem(DateTime.MaxValue); 
} 
public void Problem(DateTime optional) 
{ 
    // do your stuff here. 
} 

Si llama Problema() (sin parámetros) que llama a la función de la otra función con un parámetro.

+0

Esto es potencialmente confuso. Ambos métodos parecen a primera vista tener la misma firma. La especificación C# [nos dice] (http://stackoverflow.com/questions/2674417/c-4-conflicting-overloaded-methods-with-optional-parameters) que el compilador preferirá el método * sin * parámetros opcionales, pero no debes confiar en que todos esperen ese comportamiento. Las otras soluciones sugeridas son mucho más claras y más fáciles de mantener. –

1

valores de los parámetros loadDefault son constantes, es decir, que no puede ser string.Empty/Guid.Empty, etc Usted puede utilizar un método de sobrecarga:

void M(int intValue) 
{ 
    M(intValue, Guid.Empty); 
} 
void M(int intValue, Guid guid) 
{ 
    //do something 
} 
3

No estoy familiarizado con C# 4.0, pero en C# 3.5 Usaría sobrecarga;

public void Problem() 
{ 
    Problem(DateTime.MaxValue); 
} 
public void Problem(DateTime dt) 
{ 
} 

y llamarlo con:

Problem(); //defaults to maxvalue 
Problem(myDateTime); //uses input value 

Editar: sólo para poner una respuesta a algunas de las observaciones;

public class FooBar 
{ 
    public bool Problem() 
    { 
     //creates a default person object 
     return Problem(new Person()); 
    } 

    public void Problem(Person person) 
    { 
     //Some logic here 
     return true; 
    } 
} 

public class Person 
{ 
    public string Name { get; private set; } 
    public DateTime DOB { get; private set; } 
    public Person(string name, DateTime dob) 
    { 
     this.Name = name; 
     this.DOB = dob; 
    } 

    /// <summary> 
    /// Default constructor 
    /// </summary> 
    public Person() 
    { 
     Name = "Michael"; 
     DOB = DateTime.Parse("1980-07-21"); 
    } 
} 
+3

Si solo el método que estoy tratando de domesticar no tiene 101 parámetros ... –

+3

@Ian: jajaja, omg !! ¡Creo que tienes un problema completamente diferente allí! Use una clase de parámetro. 101 parámetros ...! –

+0

@Ian Ringrose Nunca debería tener más de 5 (?) Parámetros en cualquier método o constructor dado. Como @Daniel sugirió, abstraiga estos parámetros en una clase ProblemsArgs y pase esto en su lugar. – firefox1986

2

La respuesta simple es que no se puede con los parámetros opcionales, no creo.

puede usar una sobrecarga si este es el único parámetro. Si esto es un ejemplo para un método con muchos parámetros opcionales, entonces esto podría no ser factible.

Lo que podría hacer es asegurarse de que DateTime? y pasar null, entonces se interpreta como nullDateTime.MaxValue en su método.

Hay una buena redacción de argumentos opcionales que voy a desenterrar para usted.

EDITAR

article here

+0

-1: Su sugerencia es bastante mala, porque null generalmente se ve como un equivalente de 'default (T)'. Estarás cambiando la semántica con tu enfoque bastante. La forma correcta sería usar una sobrecarga. –

+1

@Daniel difícilmente, junto con 'predeterminado (DateTime)' con una verificación interna subsiguiente, esta es una alternativa completamente válida ... incluso el uso no cambiaría porque si se le da un 'DateTime?' Nulo todavía activaría el valor predeterminado. –

+0

una sobrecarga puede no ser factible si el método tiene muchos parámetros y el OP solo está dando un ejemplo para la pregunta. Si este es el único parámetro, entonces sí, una sobrecarga es mejor. Solo estaba sugiriendo una alternativa si él quiere usar un parámetro opcional, ya que no creo que pueda obtener su comportamiento deseado de otra manera y aún así tenerlo como un parámetro opcional. –

2

Si, como ha afirmado en una de sus comentarios, su método tiene una gran cantidad de parámetros, posiblemente puedas convertirlos a todos en una clase de parámetro y usar sus inicializadores de propiedades. Entonces no tendrá que inicializar todas las propiedades, y puede establecer la fecha en DateTime.MaxValue en el constructor de esa clase.

3

Lo que estás pidiendo hacer simplemente no es posible. DateTime.MaxValue no es una constante en tiempo de compilación; en realidad es un campo de solo lectura que se inicializa en tiempo de ejecución por un constructor estático.Eso difference se vuelve bastante crítico aquí. Los parámetros opcionales requieren constantes de tiempo de compilación, ya que hornean el valor directamente en el código.

Sin embargo, el problema real es que su método toma 101 parámetros. Nunca había visto algo que gritara tan fuerte por refactorizar. Mi recomendación sería cambiar tu método para aceptar una instancia de una clase, en su lugar. Eso también le dará más flexibilidad al especificar los valores predeterminados para las propiedades individuales de la clase. En particular, podrá especificar valores que son no constantes de tiempo de compilación.

5

De acuerdo con uno de sus comentarios, usted está tratando de hacer un método con parámetros más utilizables para las personas que llaman.
Sugiero que cree una clase de parámetro e inicialice las propiedades de esa clase con los valores predeterminados. Proporcione una sobrecarga para su método que acepte solo un parámetro: la clase de parámetro.
Esto realmente mejorará el uso de su método, porque el usuario puede incluso reutilizar su instancia de clase de parámetro si necesita cambiar solo un parámetro.

+0

Estaba pensando más en las líneas de _multiple_ clases de parámetros. Sería extraño si algunos de estos parámetros no "pertenecen juntos en grupos". –

+0

@Simen: sin conocer su código, no podemos saberlo, pero su sugerencia tiene sentido, si pertenecen en grupos. –

+0

Supongo que podría haber situaciones en las que una sola clase trata con una gran cantidad de elementos de información atómica que están muy poco relacionados: p. si está intentando definir una interfaz fuertemente tipada entre un archivo de configuración débilmente tipeado y el núcleo de su aplicación. Aún así, creo que se debe evitar pasarlos a todos a través de una sola llamada a un método. –

Cuestiones relacionadas