una sirve que publicas propiedades propiedad programacion para metodos esperaba español declarar como clase atributos agregar acceso c# reflection properties field memory-consumption

sirve - propiedades publicas c#



Usar Reflection para determinar qué campos son campos de respaldo de una propiedad (3)

El nombre del campo de respaldo de una propiedad es un detalle de implementación del compilador y siempre puede cambiar en el futuro, incluso si usted descubre el patrón.

Creo que ya has acertado en la respuesta a tu pregunta: ignora todas las propiedades .

Recuerde que una propiedad es solo una o dos funciones disfrazadas. Una propiedad solo tendrá un campo de respaldo generado por el compilador cuando lo solicite específicamente el código fuente. Por ejemplo, en C #:

public string Foo { get; set; }

Pero el creador de una clase no necesita usar propiedades generadas por el compilador como esta. Por ejemplo, una propiedad puede obtener un valor constante, múltiples propiedades pueden obtener / establecer diferentes porciones de un campo de bit, y así sucesivamente. En estos casos, no esperaría ver un único campo de respaldo para cada propiedad. Está bien ignorar estas propiedades. Su código no perderá ningún dato real.

Estoy usando la reflexión para mapear objetos. Estos objetos están en código administrado pero no tengo visibilidad de su código fuente, estructura subyacente, etc. que no sea a través de la reflexión. El objetivo general de todo esto es un mapa de memoria rudimentario de un objeto (similar en funcionalidad a los comandos DumpObject y !ObjSize ). Como tal, estoy tratando de determinar qué miembros se "cuentan doblemente" como campo y como propiedad.

Por ejemplo:

public class CalendarEntry { // private property private DateTime date { get; set;} // public field public string day = "DAY"; }

Cuando se mapea, se muestra:

  • Campos
    • día
    • k__BackingField
  • Propiedades
    • fecha

Donde una clase como esta:

public class CalendarEntry { // private field private DateTime date; // public field public string day = "DAY"; // Public property exposes date field safely. public DateTime Date { get { return date; } set { date = value; } } }

Cuando se mapea, se muestra:

  • Campos
    • día
    • fecha
  • Propiedades
    • Fecha

A primera vista, no hay nada que le diga que el "campo de respaldo" de la propiedad Date es el campo denominado date . Estoy tratando de evitar contar la fecha dos veces en este escenario ya que eso me dará una mala aproximación al tamaño de la memoria.

Lo que es más confuso / complicado es que he encontrado escenarios en los que las propiedades no siempre tienen un campo correspondiente que se mostrará a través del método Type.GetFields() , así que no puedo ignorar por completo todas las propiedades.

¿Alguna idea sobre cómo determinar si un campo de la colección devuelto por Type.GetFields() es esencialmente el campo de respaldo de alguna propiedad correspondiente devuelta por Type.GetProperties() ?

Editar: he tenido problemas para determinar en qué condiciones una propiedad no tendrá un campo correspondiente en la lista de la colección devuelta por Type.GetFields() . ¿Alguien está familiarizado con tales condiciones?

Editar 2- Encontré un buen ejemplo de cuándo el campo de respaldo de una propiedad no se incluiría en la colección devuelta por Type.GetFields() . Al mirar debajo del capó de un String tienes lo siguiente:

  • El objeto contiene una propiedad llamada FirstChar
  • El objeto contiene propiedad llamada Chars
  • El objeto contiene la propiedad denominada Length
  • El objeto contiene el campo llamado m_stringLength
  • El objeto contiene el campo llamado m_firstChar
  • El objeto contiene un campo llamado Empty
  • El objeto contiene un campo llamado TrimHead
  • El objeto contiene un campo llamado TrimTail
  • El objeto contiene un campo llamado TrimBoth
  • El objeto contiene el campo llamado charPtrAlignConst
  • El objeto contiene el campo llamado alignConst

m_firstChar y m_stringLength son los campos de respaldo de las propiedades FirstChar y Length pero el contenido real de la cadena se mantiene en la propiedad Chars. Esta es una propiedad indexada que puede indexarse ​​para devolver todos los caracteres en la Cadena pero no puedo encontrar un campo correspondiente que contenga los caracteres de una cadena. ¿Alguna idea de por qué es eso? ¿O cómo obtener el campo de respaldo de la propiedad indexada?


Para responder a su otra pregunta: ¿En qué circunstancias las propiedades no tienen campos de respaldo?

public DateTime CurrentDay { get { return DateTime.Now; } }

o propiedad puede usar cualquier otra cantidad de campos / clases de respaldo

public string FullName { get {return firstName + " " + lastName;} }


Puede ignorar todas las propiedades por completo. Si una propiedad no tiene un campo de respaldo, simplemente no consume memoria.

Además, a menos que esté dispuesto a (intentar) analizar CIL, no podrá obtener dicha asignación. Considera este código:

private DateTime today; public DateTime CurrentDay { get { return today; } }

¿Cómo espera descubrir que existe alguna relación entre el campo today y la propiedad CurrentDay ?

EDIT: con respecto a sus preguntas más recientes:

Si tiene una propiedad que contiene código como return 2.6; , entonces el valor no se mantiene en ninguna parte, esa constante se integra directamente en el código.

Con respecto a la string : la string es manejada por CLR de una manera especial. Si intenta descompilar su indexador, notará que está implementado por el CLR. Para estos pocos tipos especiales ( string , matriz, int , ...), no puede encontrar su tamaño mirando sus campos. Para todos los demás tipos, puedes.