簡體   English   中英

使用.NET的Reflection API時,記住類型元數據是否有效?

[英]Is it efficient to memoize type metadata when using .NET's Reflection API?

我知道過早的優化是萬惡之源。 但是,我想知道以下哪種選擇更有效:

  • 對於相同的類型T多次調用typeof(T).GetProperties()
  • 將檢索到的屬性存儲到Dictionary<Type, PropertyInfo[]>

這是我使用第一種方法編寫的一些代碼:

private static T MakeElement<T>(SqlDataReader reader) where T : class, new() {
    T element = new T();
    PropertyInfo[] properties = typeof(T).GetProperties(); // critical line

    foreach (PropertyInfo property in properties)
        property.SetValue(element, reader[property.Name], null);

    return element;
}

public static T RetrieveElement<T>() where T : class, new() {
    T element = null;

    actions.Add(delegate(SqlDataReader reader) {
        if (reader.Read())
            element = MakeElement<T>(reader);
    });

    Execute();
    return element;
}

public static List<T> RetrieveList<T>() where T : class, new() {
    List<T> list = new List<T>();

    actions.Add(delegate(SqlDataReader reader) {
        while (reader.Read())
            list.Add(MakeElement<T>(reader));
    });

    Execute();
    return list;
}

// For the sake of completeness, here is the Execute method.
public static void Execute() {
    SqlConnectionStringBuilder connStringBuilder = new SqlConnectionStringBuilder();
    connStringBuilder.DataSource     = DataSource;
    connStringBuilder.InitialCatalog = InitialCatalog;
    connStringBuilder.UserID         = UserID;
    connStringBuilder.Password       = Password;

    using (SqlConnection connection = new SqlConnection(connStringBuilder.ConnectionString))
    using (SqlCommand command = new SqlCommand(StoredProcedure, connection)) {
        command.CommandType = CommandType.StoredProcedure;

        SqlParameterCollection parameterCollection = command.Parameters;
        foreach (KeyValuePair<string, object> parameter in parameters)
            parameterCollection.AddWithValue(parameter.Key, parameter.Value);

        try {
            connection.Open();
            using (SqlDataReader reader = command.ExecuteReader())
                foreach (Action<SqlDataReader> action in actions) {
                    action(reader);
                    reader.NextResult();
                }
        }
        finally {
            parameters.Clear();
            actions.Clear();
        }
    }
}

我已經在考慮哪種方法可能更有效:

直接調用 GetProperties

  • 無論如何,元數據在那里。 它不必重構,只需檢索即可。

對於記憶:

  • 元數據可能采用C#應用程序無法直接理解的格式,因此GetProperties可能涉及一些預處理。
  • 元數據在那里,但PropertyInfo數組不存在,因此必須重新構造。

附加問題: .NET的Reflection API為什么使用數組而不是索引器來檢索類型元數據有什么原因?

我認為可以根據Type記住結果。 您應該根據情況進行衡量,但是我的經驗是調用GetProperties或其他反射方法會降低性能。 無論如何,GetProperties的結果在運行時不會改變。

更好的是:

public static class Memoizer<T>
{
    public static readonly PropertyInfo[] Properties = typeof(T).GetProperties();
}

只要確保不更改數組,或將其包裝在ReadOnlyCollection中即可

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM