saber que medicamentos medicamento marca listado genericos generico farmacia entre diferencia desventajas como comerciales comercial c# generics types

c# - que - medicamentos genericos y comerciales



Lo bueno de los genéricos, ¿por qué usarlos? (27)

¿Alguna vez ha escrito un método (o una clase) donde el concepto clave del método / clase no estaba estrechamente ligado a un tipo de datos específico de los parámetros / variables de instancia (lista de enlaces pensados, funciones máxima / mínima, búsqueda binaria , etc.)

¿Alguna vez has deseado poder reutilizar el algorthm / código sin recurrir a la reutilización de cortar y pegar o a comprometer la tipificación fuerte (por ejemplo, quiero una List de cadenas, no una List de cosas que espero sean cadenas)?

Es por eso que deberías querer usar genéricos (o algo mejor).

Pensé que ofrecería esta pelota de softball a quien quisiera golpearla fuera del parque. ¿Qué son los genéricos, cuáles son las ventajas de los genéricos, por qué, dónde, cómo debo usarlos? Por favor, mantenlo bastante básico. Gracias.


De la documentación de Sun Java, en respuesta a "¿por qué debería usar genéricos?":

"Generics proporciona una forma de comunicar el tipo de una colección al compilador, para que pueda verificarse. Una vez que el compilador conoce el tipo de elemento de la colección, el compilador puede verificar que ha utilizado la colección de forma coherente y puede insertar los lanzamientos correctos sobre los valores que se sacan de la colección ... El código que usa genéricos es más claro y seguro ... el compilador puede verificar en tiempo de compilación que las restricciones de tipo no se violan en el tiempo de ejecución [énfasis mío]. programa compila sin advertencias, podemos afirmar con certeza que no arrojará una ClassCastException en tiempo de ejecución. El efecto neto del uso de genéricos, especialmente en programas grandes, es la legibilidad y legibilidad mejoradas . [énfasis mío] "


El mejor beneficio para Generics es la reutilización de código. Digamos que tiene muchos objetos comerciales, y va a escribir un código MUY similar para cada entidad para realizar las mismas acciones. (IE Linq a operaciones SQL).

Con genéricos, puede crear una clase que pueda funcionar dado cualquiera de los tipos heredados de una clase base dada o implementar una interfaz determinada como esta:

public interface IEntity { } public class Employee : IEntity { public string FirstName { get; set; } public string LastName { get; set; } public int EmployeeID { get; set; } } public class Company : IEntity { public string Name { get; set; } public string TaxID { get; set } } public class DataService<ENTITY, DATACONTEXT> where ENTITY : class, IEntity, new() where DATACONTEXT : DataContext, new() { public void Create(List<ENTITY> entities) { using (DATACONTEXT db = new DATACONTEXT()) { Table<ENTITY> table = db.GetTable<ENTITY>(); foreach (ENTITY entity in entities) table.InsertOnSubmit (entity); db.SubmitChanges(); } } } public class MyTest { public void DoSomething() { var dataService = new DataService<Employee, MyDataContext>(); dataService.Create(new Employee { FirstName = "Bob", LastName = "Smith", EmployeeID = 5 }); var otherDataService = new DataService<Company, MyDataContext>(); otherDataService.Create(new Company { Name = "ACME", TaxID = "123-111-2233" }); } }

Observe la reutilización del mismo servicio dados los diferentes tipos en el método DoSomething anterior. Verdaderamente elegante!

Hay muchas otras buenas razones para usar medicamentos genéricos para su trabajo, este es mi favorito.


La ventaja principal, como lo señala Mitchel, es el tipado fuerte sin la necesidad de definir múltiples clases.

De esta forma puedes hacer cosas como estas:

List<SomeCustomClass> blah = new List<SomeCustomClass>(); blah[0].SomeCustomFunction();

Sin genéricos, debería lanzar blah [0] al tipo correcto para acceder a sus funciones.


Los genéricos en Java facilitan el polimorfismo paramétrico . Por medio de parámetros de tipo, puede pasar argumentos a tipos. Así como un método como String foo(String s) modela algún comportamiento, no solo para una cadena en particular, sino para cualquier cadena, por lo que un tipo como List<T> modela algún comportamiento, no solo para un tipo específico, sino para cualquier tipo . List<T> dice que para cualquier tipo T , hay un tipo de List cuyos elementos son T s . Así que List es en realidad un constructor de tipos . Toma un tipo como argumento y construye otro tipo como resultado.

Aquí hay un par de ejemplos de tipos genéricos que uso todos los días. Primero, una interfaz genérica muy útil:

public interface F<A, B> { public B f(A a); }

Esta interfaz dice que para algunos dos tipos, A y B , hay una función (llamada f ) que toma una A y devuelve una B Cuando implementa esta interfaz, A y B pueden ser de cualquier tipo que desee, siempre que proporcione una función f que tome la primera y devuelva la última. Aquí hay una implementación de ejemplo de la interfaz:

F<Integer, String> intToString = new F<Integer, String>() { public String f(int i) { return String.valueOf(i); } }

Antes de los genéricos, el polimorfismo se lograba subclasando usando la palabra clave extends . Con los genéricos, en realidad podemos eliminar la subclasificación y usar polimorfismo paramétrico. Por ejemplo, considere una clase parametrizada (genérica) utilizada para calcular códigos hash para cualquier tipo. En lugar de anular Object.hashCode (), usaríamos una clase genérica como esta:

public final class Hash<A> { private final F<A, Integer> hashFunction; public Hash(final F<A, Integer> f) { this.hashFunction = f; } public int hash(A a) { return hashFunction.f(a); } }

Esto es mucho más flexible que usar herencia, porque podemos seguir con el tema del uso de la composición y el polimorfismo paramétrico sin bloquear las frágiles jerarquías.

Sin embargo, los genéricos de Java no son perfectos. Puede abstraer sobre tipos, pero no puede abstraer sobre constructores de tipo, por ejemplo. Es decir, puede decir "para cualquier tipo T", pero no puede decir "para ningún tipo T que tenga un parámetro de tipo A".

Escribí un artículo sobre estos límites de los genéricos de Java, aquí.

Una gran victoria con los genéricos es que te permiten evitar las subclases. Las subclases tienden a dar como resultado jerarquías de clases frágiles que son difíciles de extender, y clases que son difíciles de entender individualmente sin mirar toda la jerarquía.

Wereas antes de genéricos puede tener clases como Widget extendido por FooWidget , BarWidget y BazWidget , con genéricos puede tener un Widget<A> clase genérico Widget<A> que toma un Foo , Bar o Baz en su constructor para darle Widget<Foo> , Widget<Bar> y Widget<Baz> .


Los genéricos evitan el golpe de rendimiento del boxeo y el desempaquetado. Básicamente, mira ArrayList vs List <T>. Ambos hacen las mismas cosas centrales, pero List <T> será mucho más rápido porque no tiene que encajonar hacia / desde el objeto.


Los genéricos le permiten usar tipeo fuerte para objetos y estructuras de datos que deberían poder contener cualquier objeto. También elimina los tipos de letra tediosos y caros al recuperar objetos de estructuras genéricas (boxeo / unboxing).

Un ejemplo que usa ambos es una lista vinculada. ¿De qué serviría una clase de lista enlazada si solo pudiera usar el objeto Foo? Para implementar una lista vinculada que pueda manejar cualquier tipo de objeto, la lista vinculada y los nodos en una clase interna de nodo hipotético deben ser genéricos si desea que la lista contenga solo un tipo de objeto.


Los genéricos te permiten crear objetos fuertemente tipados, pero no tienes que definir el tipo específico. Creo que el mejor ejemplo útil es la Lista y clases similares.

Usando la lista genérica puede tener una Lista de Lista de Lista lo que desee y siempre puede hacer referencia a la tipificación fuerte, no tiene que convertir o algo así como lo haría con una matriz o lista estándar.


No olvide que los genéricos no solo son utilizados por las clases, sino que también pueden usarse por métodos. Por ejemplo, tome el siguiente fragmento:

private <T extends Throwable> T logAndReturn(T t) { logThrowable(t); // some logging method that takes a Throwable return t; }

Es simple, pero se puede usar muy elegantemente. Lo bueno es que el método devuelve lo que fue que se le dio. Esto ayuda cuando se manejan excepciones que necesitan ser devueltas a la persona que llama:

... } catch (MyException e) { throw logAndReturn(e); }

El punto es que no pierdes el tipo pasándolo por un método. Puede lanzar el tipo correcto de excepción en lugar de solo un Throwable , que sería todo lo que podría hacer sin los genéricos.

Este es solo un simple ejemplo de un uso para métodos genéricos. Hay muchas otras cosas buenas que puedes hacer con métodos genéricos. Lo más genial, en mi opinión, es el tipo de inferir con genéricos. Tome el siguiente ejemplo (tomado de Effective Java 2nd Edition de Josh Bloch):

... Map<String, Integer> myMap = createHashMap(); ... public <K, V> Map<K, V> createHashMap() { return new HashMap<K, V>(); }

Esto no hace mucho, pero reduce el desorden cuando los tipos genéricos son largos (o anidados, es decir, Map<String, List<String>> ).


Para dar un buen ejemplo. Imagina que tienes una clase llamada Foo

public class Foo { public string Bar() { return "Bar"; } }

Ejemplo 1 Ahora quiere tener una colección de objetos Foo. Tienes dos opciones, LIst o ArrayList, que funcionan de manera similar.

Arraylist al = new ArrayList(); List<Foo> fl = new List<Foo>(); //code to add Foos al.Add(new Foo()); f1.Add(new Foo());

En el código anterior, si trato de agregar una clase de FireTruck en lugar de Foo, ArrayList lo agregará, pero la Lista genérica de Foo hará que se genere una excepción.

Ejemplo dos

Ahora tiene sus dos listas de matriz y desea llamar a la función Bar () en cada una. Como hte ArrayList está lleno de objetos, debe lanzarlos antes de poder llamar a la barra. Pero dado que la Lista genérica de Foo solo puede contener Foos, puede llamar a Bar () directamente en esos.

foreach(object o in al) { Foo f = (Foo)o; f.Bar(); } foreach(Foo f in fl) { f.Bar(); }


Realmente odio repetirme. Odio escribir lo mismo más a menudo que lo que tengo que hacer. No me gusta repetir las cosas varias veces con pequeñas diferencias.

En lugar de crear:

class MyObjectList { MyObject get(int index) {...} } class MyOtherObjectList { MyOtherObject get(int index) {...} } class AnotherObjectList { AnotherObject get(int index) {...} }

Puedo construir una clase reutilizable ... (en el caso de que no quieras usar la colección sin procesar por algún motivo)

class MyList<T> { T get(int index) { ... } }

Ahora soy 3 veces más eficiente y solo tengo que mantener una copia. ¿Por qué NO querrías mantener menos código?

Esto también es cierto para las clases que no son de colección, como una Callable<T> o una Reference<T> que tiene que interactuar con otras clases. ¿Realmente desea extender Callable<T> y Future<T> y cualquier otra clase asociada para crear versiones de tipo seguro?

Yo no.


Sé que esta es una pregunta de C #, pero los generics se usan en otros idiomas, y su uso / objetivos son bastante similares.

Las colecciones de Java usan generics desde Java 1.5. Entonces, un buen lugar para usarlos es cuando está creando su propio objeto similar a una colección.

Un ejemplo que veo casi en todas partes es una clase Pair, que contiene dos objetos, pero necesita tratar esos objetos de una manera genérica.

class Pair<F, S> { public final F first; public final S second; public Pair(F f, S s) { first = f; second = s; } }

Siempre que use esta clase Pair, puede especificar qué tipo de objetos desea que trate y cualquier tipo de problema de conversión aparecerá en tiempo de compilación, en lugar de en tiempo de ejecución.

Los genéricos también pueden tener sus límites definidos con las palabras clave ''super'' y ''extends''. Por ejemplo, si quiere tratar con un tipo genérico pero quiere asegurarse de que amplíe una clase llamada Foo (que tiene un método setTitle):

public class FooManager <F extends Foo>{ public void setTitle(F foo, String title) { foo.setTitle(title); } }

Si bien no es muy interesante por sí mismo, es útil saber que cada vez que maneje un FooManager, sabrá que manejará los tipos de MyClass, y que MyClass se extenderá a Foo.


Si tuviera que buscar en la base de datos de errores de Java justo antes de que se lanzara 1.5, encontraría siete veces más errores con NullPointerException que ClassCastException . Entonces, no parece que sea una gran característica encontrar errores, o al menos errores que persisten después de un poco de prueba de humo.

Para mí, la gran ventaja de los genéricos es que documentan en código la información de tipo importante. Si no quisiera que ese tipo de información esté documentada en código, entonces utilizaría un lenguaje de tipado dinámico, o al menos un lenguaje con inferencia de tipo más implícita.

Mantener las colecciones de un objeto para sí mismo no es un mal estilo (pero el estilo común es ignorar eficazmente la encapsulación). Más bien depende de lo que estás haciendo. Pasar colecciones a "algoritmos" es un poco más fácil de verificar (en o antes del tiempo de compilación) con genéricos.


Simplemente me gustan porque te dan una forma rápida de definir un tipo personalizado (como los uso de todos modos).

Entonces, por ejemplo, en lugar de definir una estructura que consta de una cadena y un número entero, y luego tener que implementar un conjunto completo de objetos y métodos sobre cómo acceder a una matriz de esas estructuras, etc., puede hacer un diccionario

Dictionary<int, string> dictionary = new Dictionary<int, string>();

Y el compilador / IDE hace el resto del trabajo pesado. Un diccionario en particular le permite usar el primer tipo como clave (sin valores repetidos).


el jvm arroja de todos modos ... crea código de forma implícita que trata el tipo genérico como "Objeto" y crea moldes para la instanciación deseada. Los genéricos de Java son solo azúcar sintáctico.


No necesitar el encasillado es una de las mayores ventajas de los genéricos de Java , ya que realizará la verificación de tipos en tiempo de compilación. Esto reducirá la posibilidad de ClassCastException s que se puede lanzar en el tiempo de ejecución, y puede conducir a un código más robusto.

Pero sospecho que eres completamente consciente de eso.

Cada vez que miro a Generics me da dolor de cabeza. En mi opinión, la mejor parte de Java es su simplicidad y la sintaxis mínima y los genéricos no son simples y añaden una cantidad significativa de sintaxis nueva.

Al principio, tampoco vi el beneficio de los genéricos. Comencé a aprender Java a partir de la sintaxis 1.4 (a pesar de que Java 5 estaba fuera en ese momento) y cuando encontré genéricos, sentí que era más código para escribir, y realmente no entendía los beneficios.

Los IDEs modernos hacen que escribir código con genéricos sea más fácil.

La mayoría de los IDEs modernos y decentes son lo suficientemente inteligentes como para ayudar a escribir código con genéricos, especialmente con la finalización de código.

Aquí hay un ejemplo de hacer un Map<String, Integer> con un HashMap . El código que tendré que escribir es:

Map<String, Integer> m = new HashMap<String, Integer>();

Y de hecho, eso es mucho para escribir solo para hacer un nuevo HashMap . Sin embargo, en realidad, solo tuve que escribir esto mucho antes de que Eclipse supiera lo que necesitaba:

Map<String, Integer> m = new Ha Ctrl + Espacio

Es cierto que tuve que seleccionar HashMap de una lista de candidatos, pero básicamente el IDE sabía qué agregar, incluidos los tipos genéricos. Con las herramientas adecuadas, usar genéricos no es tan malo.

Además, dado que los tipos son conocidos, cuando se recuperan elementos de la colección genérica, el IDE actuará como si ese objeto ya fuera un objeto de su tipo declarado; no hay necesidad de convertir el IDE para saber cuál es el tipo de objeto es.

Una ventaja clave de los genéricos proviene de la forma en que funciona bien con las nuevas características de Java 5. Aquí hay un ejemplo de lanzar enteros a un Set y calcular su total:

Set<Integer> set = new HashSet<Integer>(); set.add(10); set.add(42); int total = 0; for (int i : set) { total += i; }

En esa pieza de código, hay tres nuevas características de Java 5 presentes:

Primero, los genéricos y el autoboxing de primitivas permiten las siguientes líneas:

set.add(10); set.add(42);

El número entero 10 es autoboxed en un Integer con el valor de 10 . (Y lo mismo para 42 ). Luego ese Integer se arroja al Set que se sabe que contiene Integer . Intentar arrojar una String provocaría un error de compilación.

A continuación, para for-each loop toma los tres de los siguientes:

for (int i : set) { total += i; }

Primero, el Set contiene Integer se usa en un bucle for-each. Cada elemento se declara como int y se permite a medida que el Integer se vuelve a empaquetar en la primitiva int . Y el hecho de que este desempaquetado ocurra es conocido porque los genéricos se usaron para especificar que había Integer retenidos en el Set .

Los genéricos pueden ser el pegamento que reúne las nuevas características introducidas en Java 5, y simplemente hace que la codificación sea más simple y segura. Y la mayoría de las veces, los IDEs son lo suficientemente inteligentes como para ayudarte con buenas sugerencias, por lo que, en general, no será mucho más tipeo.

Y francamente, como se puede ver en el ejemplo de Set , creo que la utilización de las características de Java 5 puede hacer que el código sea más conciso y robusto.

Editar - Un ejemplo sin genéricos

La siguiente es una ilustración del ejemplo de Set anterior sin el uso de genéricos. Es posible, pero no es exactamente agradable:

Set set = new HashSet(); set.add(10); set.add(42); int total = 0; for (Object o : set) { total += (Integer)o; }

(Nota: el código anterior generará una advertencia de conversión no verificada en tiempo de compilación).

Al usar colecciones no genéricas, los tipos que se ingresan en la colección son objetos de tipo Object . Por lo tanto, en este ejemplo, un Object es lo que se add al conjunto.

set.add(10); set.add(42);

En las líneas anteriores, el autoboxing está en juego: el valor int primitivo 10 y 42 se están autocapturando en objetos Integer , que se están agregando al Set . Sin embargo, tenga en cuenta que los objetos Integer se manejan como Object , ya que no hay información de tipo para ayudar al compilador a saber qué tipo debe esperar el Set .

for (Object o : set) {

Esta es la parte que es crucial. El motivo por el que funciona el ciclo for-each es porque el Set implementa la interfaz Iterable , que devuelve un Iterator con información de tipo, si está presente. ( Iterator<T> , eso es)

Sin embargo, dado que no hay información de tipo, el Set devolverá un Iterator que devolverá los valores en el Set como Object s, y es por eso que el elemento que se recupera en el bucle for-each debe ser de tipo Object .

Ahora que el Object se recupera del Set , se debe convertir a un Integer manualmente para realizar la suma:

total += (Integer)o;

Aquí, un tipo de transmisión se realiza desde un Object a un Integer . En este caso, sabemos que esto siempre funcionará, pero el encasillado manual siempre me hace sentir que es un código frágil que podría dañarse si se realiza un cambio menor en otro lugar. (Siento que cada tipocast es una ClassCastException esperando a suceder, pero estoy divagando ...)

El Integer ahora está desagrupado en un int y se le permite realizar la suma en el total variable int .

Espero poder ilustrar que las nuevas características de Java 5 se pueden usar con código no genérico, pero simplemente no es tan limpio y sencillo como escribir código con genéricos. Y, en mi opinión, para aprovechar al máximo las nuevas características en Java 5, uno debería buscar en los genéricos, si al menos, permite verificaciones en tiempo de compilación para evitar que los tipos de letra inválidos emitan excepciones en el tiempo de ejecución.


A couple of things to add/expand on (speaking from the .NET point of view):

Generic types allow you to create role-based classes and interfaces. This has been said already in more basic terms, but I find you start to design your code with classes which are implemented in a type-agnostic way - which results in highly reusable code.

Generic arguments on methods can do the same thing, but they also help apply the "Tell Don''t Ask" principle to casting, ie "give me what I want, and if you can''t, you tell me why".


Another advantage of using Generics (especially with Collections/Lists) is you get Compile Time Type Checking. This is really useful when using a Generic List instead of a List of Objects.



I use them for example in a GenericDao implemented with SpringORM and Hibernate which look like this

public abstract class GenericDaoHibernateImpl<T> extends HibernateDaoSupport { private Class<T> type; public GenericDaoHibernateImpl(Class<T> clazz) { type = clazz; } public void update(T object) { getHibernateTemplate().update(object); } @SuppressWarnings("unchecked") public Integer count() { return ((Integer) getHibernateTemplate().execute( new HibernateCallback() { public Object doInHibernate(Session session) { // Code in Hibernate for getting the count } })); } . . . }

By using generics my implementations of this DAOs force the developer to pass them just the entities they are designed for by just subclassing the GenericDao

public class UserDaoHibernateImpl extends GenericDaoHibernateImpl<User> { public UserDaoHibernateImpl() { super(User.class); // This is for giving Hibernate a .class // work with, as generics disappear at runtime } // Entity specific methods here }

My little framework is more robust (have things like filtering, lazy-loading, searching). I just simplified here to give you an example

I, like Steve and you, said at the beginning "Too messy and complicated" but now I see its advantages


If your collection contains value types, they don''t need to box/unbox to objects when inserted into the collection so your performance increases dramatically. Cool add-ons like resharper can generate more code for you, like foreach loops.


In summary, generics allow you to specify more precisily what you intend to do (stronger typing).

This has several benefits for you:

  • Because the compiler knows more about what you want to do, it allows you to omit a lot of type-casting because it already knows that the type will be compatible.

  • This also gets you earlier feedback about the correctnes of your program. Things that previously would have failed at runtime (eg because an object couldn''t be casted in the desired type), now fail at compile-time and you can fix the mistake before your testing-department files a cryptical bug report.

  • The compiler can do more optimizations, like avoiding boxing, etc.


Single most reason is they provide Type safety

List<Customer> custCollection = new List<Customer>;

as opposed to,

object[] custCollection = new object[] { cust1, cust2 };

as a simple example.


Using generics for collections is just simple and clean. Even if you punt on it everywhere else, the gain from the collections is a win to me.

List<Stuff> stuffList = getStuff(); for(Stuff stuff : stuffList) { stuff.do(); }

vs

List stuffList = getStuff(); Iterator i = stuffList.iterator(); while(i.hasNext()) { Stuff stuff = (Stuff)i.next(); stuff.do(); }

o

List stuffList = getStuff(); for(int i = 0; i < stuffList.size(); i++) { Stuff stuff = (Stuff)stuffList.get(i); stuff.do(); }

That alone is worth the marginal "cost" of generics, and you don''t have to be a generic Guru to use this and get value.


Los genéricos también le brindan la capacidad de crear más objetos / métodos reutilizables a la vez que proporciona soporte específico para el tipo. También ganas mucho rendimiento en algunos casos. No conozco la especificación completa en Java Generics, pero en .NET puedo especificar restricciones en el parámetro Type, como Implements a Interface, Constructor y Derivation.


  • Le permite escribir código / usar métodos de biblioteca que son seguros para el tipo, es decir, se garantiza que List <string> sea una lista de cadenas.
  • Como resultado del uso de genéricos, el compilador puede realizar comprobaciones en tiempo de compilación del código de tipo seguridad, es decir, ¿está tratando de poner un int en esa lista de cadenas? El uso de ArrayList haría que fuera un error de tiempo de ejecución menos transparente.
  • Más rápido que usar objetos ya que evita el boxeo / unboxing (donde .net tiene que convertir tipos de valores a tipos de referencia o viceversa ) o el fundido desde objetos al tipo de referencia requerido.
  • Le permite escribir código que es aplicable a muchos tipos con el mismo comportamiento subyacente, es decir, un Diccionario <cadena, int> usa el mismo código subyacente que un Diccionario <Fecha y hora, doble>; usando genéricos, el equipo del marco solo tuvo que escribir una pieza de código para lograr ambos resultados con las ventajas antes mencionadas también.

  • Colecciones tipificadas: incluso si no desea utilizarlas, es probable que tenga que tratarlas desde otras bibliotecas, otras fuentes.

  • Tipeo genérico en la creación de clases:

    clase pública Foo <T> {public T get () ...

  • Evitar el casting: siempre me han desagradado cosas como

    nuevo comparador {public int compareTo (Object o) {if (o instanceof classIcareAbout) ...

Donde esencialmente está buscando una condición que solo debería existir porque la interfaz se expresa en términos de objetos.

Mi reacción inicial a los genéricos fue similar a la tuya: "demasiado desordenada, demasiado complicada". Mi experiencia es que después de usarlos por un tiempo, te acostumbras a ellos, y el código sin ellos se siente menos claramente especificado, y es menos cómodo. Aparte de eso, el resto del mundo java los usa así que vas a tener que seguir con el programa eventualmente, ¿verdad?