visual targetframework studio standard net library how c# .net comparison bcl

c# - targetframework - net standard linux



¿Hay algún tipo de "ReferenceComparer" en.NET? (2)

Hay varios lugares en BCL donde se puede hacer uso de IEqualityComparer . Como Enumerable.Contains o Dictionary Constructor . Puedo proporcionar mi comparador si no estoy satisfecho con el default .

A veces quiero saber si la colección contiene ese mismo objeto al que hago referencia. No el que se considera "igual" en ningún otro significado.
La pregunta es: ¿ Existe un comparador de igualdad estándar en el BCL que se base solo en el método ReferenceEquals ?

El que yo mismo escribí es este:

class ReferenceComparer<T> : IEqualityComparer<T> where T : class { private static ReferenceComparer<T> m_instance; public static ReferenceComparer<T> Instance { get { return m_instance ?? (m_instance = new ReferenceComparer<T>()); } } public bool Equals(T x, T y) { return ReferenceEquals(x, y); } public int GetHashCode(T obj) { return RuntimeHelpers.GetHashCode(obj); } }

No lo probé a fondo ni consideré muchos escenarios, pero parece hacer que Enumerable.Contains y Dictionary bastante felices.


Por lo que sé, el BCL no expone ningún tipo público que implemente IEqualityComparer<T> con igualdad de referencia a partir de .NET 4.0.

Sin embargo, parece que hay un montón de tipos internos que hacen esto, como:

  • System.Dynamic.Utils.ReferenceEqualityComparer<T> (en System.Core)
  • System.Xaml.Schema.ReferenceEqualityComparer<T> (en System.Xaml).

Eché un vistazo a las implementaciones de estos dos tipos con reflector, y te alegrará saber que ambos parecen implementarse de una manera que es prácticamente idéntica a la tuya, excepto que no usan la inicialización perezosa. para la instancia estática (la crean en el constructor estático para el tipo).

El único "problema" posible que se me ocurre con su implementación es que la inicialización lenta no es segura para subprocesos, pero dado que las instancias son "baratas" y no se aferran a ningún estado, eso no debería crear ningún error o mayor problemas de rendimiento. Sin embargo, si desea imponer el patrón singleton, tendrá que hacerlo correctamente.


Terminé usando esta solución también porque no pude encontrar ninguna solución.

Para corregir la implementación no segura para subprocesos, puede utilizar fácilmente un iniciador estático.

public static ReferenceComparer<T> Instance => new ReferenceComparer<T>();

(perdón por la respuesta en lugar de un comentario a un hilo de votación ascendente, todavía tengo una cuenta nueva sin derechos de comentarios).