una tipo recortar parámetros para objeto metodos hay extraer este ejemplos definido dato clase caracteres cadena .net string constraints

.net - tipo - string[] c# ejemplos



System.String: ¿por qué no implementa un constructor sin parámetros? (11)

"[¿Por qué no] System.String ... contiene [un] constructor sin parámetros?"

Porque así fue como fue diseñado. Como puede ver en la variedad de respuestas y opiniones aquí, ni siquiera existe un consenso claro sobre la necesidad o implementación de un constructor sin parámetros. Obviamente, es técnicamente posible tener un constructor predeterminado que se String.Empty en String.Empty , por lo que el equipo de BCL no lo pensó (poco probable), o pensó que no era un escenario que valiera la pena (probable). FWIW, estoy de acuerdo, no veo una razón por la cual un ctor predeterminado en la string sea ​​importante.

"¿Por qué crees que la nueva cadena () es inútil y, por ejemplo, la nueva int () no es inútil? Realmente no puedo ver la diferencia".

La diferencia es que int es un ValueType . Se required que los ValueType tengan un constructor predeterminado, e inicializa el tipo a un valor predeterminado. string es un tipo de referencia: ya tiene un valor predeterminado: null (igual que todos los demás tipos de referencia).

Por supuesto, no está de acuerdo: tiene un escenario específico que cree que se implementa mejor con un ctor predeterminado en la string . Sin conocer detalles específicos sobre su escenario, es difícil comentarlo de manera inteligente. Pero, mi conjetura es que estás tratando con la obsesión primitiva . Si string.Empty tiene sentido para sus datos particulares, entonces probablemente debería tener una clase a su alrededor. Su constructor por defecto puede inicializar una string.Empty . string.Empty .

E: ¿Por qué obsesión primitiva?

Iba a escribir sobre ORMs u otros mapeadores (los pocos lugares en los que puedo pensar que where T:new() es útil) y cómo, en lugar de tratar de mapear string , deberías usar un objeto comercial personalizado. Pero, después de hacer un código de ejemplo, estoy bastante atascado. No puedo pensar en ningún escenario que tenga sentido con una new string() == string.Empty .

Quería preguntar cuál es la idea detrás del hecho de que System.String no contiene un constructor sin parámetros.

Debido a esto, no puede usar este tipo cuando hay una nueva restricción ().

ACTUALIZAR

¿Por qué crees que new string () es inútil y, por ejemplo, new int () no es inútil? Realmente no puedo ver la diferencia. Realmente me gustaría poder usar una nueva restricción () en la cadena, ya que lo que estoy esperando es String.Empty.

Actualización2

Sé que int es un tipo de valor y todos los tipos de valor tienen un constructor predeterminado sin parámetros. Me refería a la respuesta de @John Saunders (y respuestas similares) que afirmaban que decir que el nuevo String () básicamente no sirve para nada. Entonces, si new String () no significa nada útil, ¿qué tiene de útil el nuevo int ()? También entiendo que es importante que los tipos de valor tengan constructores predeterminados sin parámetros. Además, creo que sería muy bueno que la cadena tuviera un constructor predeterminado sin parámetros. La falta de un constructor sin parámetros significa para mí que un objeto simplemente no puede existir sin un parámetro que lo inicialice. En mi opinión, la cadena no necesita ningún parámetro porque podría estar vacía. Hice esta pregunta porque quería saber si hay alguna razón importante para que la cadena no tenga un constructor sin parámetros o simplemente es diseño o algo más.

ACTUALIZACIÓN3

Supongo que será la última actualización, ya que parece más una publicación de blog que una pregunta. En java, las cadenas también son inmutables y la nueva cadena () es perfectamente legal. Sin embargo, la documentación para el constructor sin parámetros dice:

Inicializa un objeto String recién creado para que represente una secuencia de caracteres vacía. Tenga en cuenta que el uso de este constructor es innecesario ya que las cadenas son inmutables.

Actualización 4

Ok, última actualización;) Estoy de acuerdo con John Saunders. Estaba usando un código que tenía una restricción new () y funcionó bien para las clases personalizadas. Entonces, mi colega necesita cambiar el código por ints y estuvo bien. Luego lo cambiamos por cadena y tuvimos un problema. Cuando ahora lo pienso, supongo que el código que estamos utilizando debe cambiarse para reflejar que necesitamos tipos escalares, no clases que tengan constructores sin parámetros. Dicho todo esto, sigo pensando que es un poco inconsistente que pueda escribir new int () y no puede escribir una nueva cadena () (sí, entiendo que int es un tipo de valor;)). ¡Gracias por todas sus respuestas!

Gracias de antemano por la ayuda.


¿Por qué crees que new string () es inútil y, por ejemplo, new int () no es inútil?

Volvamos a lo básico y hablemos sobre los tipos de referencia y valor.

Cuando crea un int, long, point, o lo que sea, el tipo de valor se asigna en la pila, por lo que un int reserva 4 bytes en la pila, la longitud es de 8 bytes, y así sucesivamente. El espacio de pila reservado para el tipo de valor es cero, nunca es posible referirse a la dirección de tipos de valor en la pila y obtener un valor nulo. Por lo tanto, los constructores predeterminados en los tipos de valor probablemente se deben más a las peculiaridades en la asignación de pila que a la utilidad (tal vez alguien en MS podría dar más información).

En cualquier caso, creo que System.String carece de un constructor predeterminado debido a un pésimo diseño de API .

Los objetos inmutables, en particular los enumerables, casi siempre exponen un constructor predeterminado para instanciar una colección vacía.

Creo que Microsoft tenía buenas intenciones: es mejor usar "" o String.Empty siempre que necesite una cadena vacía porque está internada, y no es tan útil para hacer una new String() cada vez, pero aparece Yo como la manera de Microsoft de "salvar a los desarrolladores de sí mismos".

(Gracias, Microsoft, aprecio tu apoyo paternalista, pero soy perfectamente capaz de cuidarme a mí mismo. Si no quiero crear varias instancias del mismo objeto, lo almacenaré como lo hago para el bagillion otros tipos con un constructor por defecto.)

Por ahora, debe tratar los objetos sin constructores predeterminados como un caso especial de todo lo demás. Volver a escribir

public void DoSomething<T>() where T : new() { ... }

Como dos métodos:

public void DoSomething<T>() where T : new() { DoSomething(() => new T()); } public void DoSomething<T>(Func<T> constructor) { }

Los clientes a su código deben decidir qué función llamar por sí mismos.

Ahora, alguien que mira el código anterior podría preguntar por qué pasaría un constructor en lugar de un objeto real al método, es decir,

public void DoSomething<T>(T obj) { ... }

Puede haber motivos, por ejemplo, si no se garantiza que se llame al método constructor. Trabajé en una aplicación de formas complejas en la que hacer clic en los botones o en los elementos del menú aparecería un formulario o, si el formulario ya estaba abierto, lo enfocaríamos. Así que tuvimos algo como:

public T ShowForm<T>(Func<T> constructor) where T : Form { T res = default(T); foreach(Form f in Application.OpenForms) { if (f is T) { res = (T)f; break; } } if (res == null) res = constructor(); res.Focus(); return res; }

No pudimos usar la nueva restricción, ya que algunas formas tenían constructores no predeterminados, por lo que la estrategia anterior finalmente funcionó muy bien y nos ahorró la molestia de crear una tonelada de clases de fábrica.


¿Qué es una cadena sin una cadena real?

Puedes hacerlo:

String s = "hello world";

Y una vez que tienes la cadena no puedes alterar esa cadena específica (las cadenas son inmutables). Si desea declarar una cadena vacía, simplemente haga lo siguiente:

string s = string.empty


Desde http://msdn.microsoft.com/en-gb/library/system.string.aspx

Un objeto String se llama inmutable (solo lectura) porque su valor no se puede modificar una vez que se ha creado. Los métodos que parecen modificar un objeto String realmente devuelven un nuevo objeto String que contiene la modificación. Si es necesario modificar el contenido real de un objeto similar a una cadena, use la clase System.Text.StringBuilder .

Así que un constructor sin parámetros no tendría sentido.


Dirigir específicamente cómo evitar el new() problema de restricción new() cuando trabaja con tipos genéricos:

Incluya el siguiente campo, propiedad y método:

private readonly Func<T> _defaultValueFactory = (Func<T>)DefaultT; private Func<T> DefaultValueFactory { get { return _defaultValueFactory; } } private static T DefaultT() { return default(T); }

También incluya un constructor para su tipo que tome una función Func<T> defaultValueFactory .

Donde sea que use normalmente la new T() , use DefaultValueFactory() lugar.


Es un problema común en el código genérico. C ++ lo resuelve con la especialización de plantillas, pero C # no lo admite.

Sin embargo, no se puede hacer de forma limpia en C #; su mejor opción es usar la restricción de class lugar, luego usar el truco basado en la reflexión para construir una T defecto o usar String.Empty si T es System.String . Perderá la verificación del compilador para usar otras clases que no son construibles por defecto.

Aquí hay otra opción:

class MyClass<T> where T : class { public MyClass(T default) private T m_default; }; MyClass<object> instance = new MyClass<object>(new object()); MyClass<string> instance = new MyClass<string>(String.Empty);

Y otro:

class MyClass<T> where T : class { static SetDefault(T def) { s_default = def; } static T s_default; }; MyClass<object> instance = new MyClass<object>(new object()); MyClass<string> instance = new MyClass<string>(String.Empty);


Int32 es una estructura. Las estructuras SIEMPRE tienen un constructor sin parámetros. No tiene nada que ver con su utilidad, incluso si Microsoft decidió que el constructor sin parámetros de Int32 es completamente inútil, no hay absolutamente nada que puedan hacer al respecto. Y si quisieran cambiar el comportamiento de las estructuras ahora, sería un gran cambio. Tampoco es factible convertir Int32 en una clase, ya que hay una razón por la que .net admite tanto el tipo de Valor como el de Referencia (he escuchado de los chicos de Java que el hecho de que Integer sea una clase causa algunos problemas, pero no puedo comentar). en eso realmente).

Cadena por otro lado es una clase. Para las clases, puede controlar si tiene o no un constructor sin parámetros, por lo que aquí es posible ver que es inútil y omitirlo.


Lo que haría

String s = new String();

entregarte

String s = String.Empty;

o

String s = null;


Supongo que quieres poder definir una clase que sea así:

public class SpecializedCollection<T> where T : new() { private List<T> _startingItems; public SpecializedCollection(int startingSize) { _startingItems = new List<T>(startingSize); for (int i = 0; i < startingSize; ++i) _startingItems.Add(new T()); } // ... lots more code }

Estoy en lo cierto Si desea que esto sea más flexible, para permitir tipos que pueden no tener un constructor sin parámetros predeterminado, siempre puede hacer esto:

public class SpecializedCollection<T> { private List<T> _startingItems; // note: here we leave it up to the caller to specify // how T objects will be instantiated public SpecializedCollection(int startingSize, Func<T> generator) { _startingItems = new List<T>(startingSize); for (int i = 0; i < startingSize; ++i) _startingItems.Add(generator.Invoke()); } }

Luego, puedes crear una SpecializedCollection<string> como:

var strings = new SpecializedCollection<string>(10, () => string.Empty);

Por supuesto, si desea ofrecer un constructor predeterminado que intente construir objetos utilizando un constructor sin parámetros para T , siempre podría sobrecargar el constructor:

public SpecializedCollection(int startingSize) : this(startingSize, Activator.CreateInstance<T>()) { }

Lo anterior no funcionaría para la string , por supuesto, pero lo haría para cualquier clase con un constructor sin parámetros (es decir, cualquier cosa que hubiera funcionado con la restricción anterior where T : new() ).


Todas las cuerdas vacías son iguales. ¿Por qué quieres crear uno? Puedes usar String.Empty o simplemente "".


Si pudieras usar

string s = new string();

¿Qué harías con eso? Las cuerdas son inmutables.

Algunos lectores han pensado que estaba diciendo que un constructor de cadenas sin parámetros sería inútil. Eso no es lo que quise decir. Quise decir que la cadena vacía creada a partir de dicho constructor sería inútil en el resto del código.

Tenga en cuenta lo que el OP dijo que quería hacer:

public void SomeMethod<T>() where T : new() { var t = new T(); // Do _what_ now? } // Call: SomeMethod<string>();

No veo lo que podrías hacer con t después de que fue construido.