.NET Framework
Reflexion
Sök…
Vad är en församling?
Församlingar är byggstenen i alla Common Language Runtime- applikationer (CLR) . Varje typ du definierar, tillsammans med dess metoder, egenskaper och deras bytkod, sammanställs och förpackas i en montering.
using System.Reflection;
Assembly assembly = this.GetType().Assembly;
Församlingar är självdokumenterande: de innehåller inte bara typer, metoder och deras IL-kod, utan också metadata som är nödvändiga för att inspektera och konsumera dem, både vid sammanställning och driftstid:
Assembly assembly = Assembly.GetExecutingAssembly();
foreach (var type in assembly.GetTypes())
{
Console.WriteLine(type.FullName);
}
Församlingar har namn som beskriver deras fulla, unika identitet:
Console.WriteLine(typeof(int).Assembly.FullName);
// Will print: "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Om detta namn innehåller ett PublicKeyToken
kallas det ett starkt namn . Att stärka namnet på en enhet är processen att skapa en signatur genom att använda den privata nyckeln som motsvarar den offentliga nyckeln som distribueras med enheten. Denna signatur läggs till i församlingsmanifestet, som innehåller namnen och hasherna på alla filer som utgör församlingen, och dess PublicKeyToken
blir en del av namnet. Församlingar som har samma starka namn bör vara identiska; starka namn används i versionering och för att förhindra monteringskonflikter.
Hur man skapar ett objekt av T med Reflektion
Med standardkonstruktören
T variable = Activator.CreateInstance(typeof(T));
Med hjälp av parametrerad konstruktör
T variable = Activator.CreateInstance(typeof(T), arg1, arg2);
Skapa objekt och inställningsegenskaper med reflektion
Låt oss säga att vi har en klass Classy
som har egendom Propertua
public class Classy
{
public string Propertua {get; set;}
}
ställer Propertua
in Propertua
med reflektion:
var typeOfClassy = typeof (Classy);
var classy = new Classy();
var prop = typeOfClassy.GetProperty("Propertua");
prop.SetValue(classy, "Value");
Få ett attribut av enum med reflektion (och cache-cache)
Attribut kan vara användbara för att beteckna metadata på enums. Att få värdet på detta kan vara långsamt, så det är viktigt att cache-resultat.
private static Dictionary<object, object> attributeCache = new Dictionary<object, object>();
public static T GetAttribute<T, V>(this V value)
where T : Attribute
where V : struct
{
object temp;
// Try to get the value from the static cache.
if (attributeCache.TryGetValue(value, out temp))
{
return (T) temp;
}
else
{
// Get the type of the struct passed in.
Type type = value.GetType();
FieldInfo fieldInfo = type.GetField(value.ToString());
// Get the custom attributes of the type desired found on the struct.
T[] attribs = (T[])fieldInfo.GetCustomAttributes(typeof(T), false);
// Return the first if there was a match.
var result = attribs.Length > 0 ? attribs[0] : null;
// Cache the result so future checks won't need reflection.
attributeCache.Add(value, result);
return result;
}
}
Jämför två objekt med reflektion
public class Equatable
{
public string field1;
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
var type = obj.GetType();
if (GetType() != type)
return false;
var fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
foreach (var field in fields)
if (field.GetValue(this) != field.GetValue(obj))
return false;
return true;
}
public override int GetHashCode()
{
var accumulator = 0;
var fields = GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
foreach (var field in fields)
accumulator = unchecked ((accumulator * 937) ^ field.GetValue(this).GetHashCode());
return accumulator;
}
}
Obs: detta exempel gör en fältbaserad jämförelse (ignorera statiska fält och egenskaper) för enkelhetens skull