プロパティが internal とマークされている場合、抽象クラスで定義されたプロパティの属性にアクセスする際に問題が発生します。コード例を次に示します。
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class CustomAttribute : Attribute
{
}
public abstract class BaseModel
{
[CustomAttribute]
protected DateTimeOffset GenerationTime { get { return DateTimeOffset.Now; } }
[CustomAttribute]
public abstract string FirstName { get; } // Attribute found in .NET 3.5
[CustomAttribute]
internal abstract string LastName { get; } // Attribute not found in .NET 3.5
}
public class ConcreteModel : BaseModel
{
public override string FirstName { get { return "Edsger"; } }
internal override string LastName { get { return "Dijkstra"; } }
[CustomAttribute]
internal string MiddleName { get { return "Wybe"; } }
}
class Program
{
static void Main(string[] args)
{
ConcreteModel model = new ConcreteModel();
var props = model.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).ToList();
List<PropertyInfo> propsFound = new List<PropertyInfo>(), propsNotFound = new List<PropertyInfo>();
for (int i = props.Count - 1; i >= 0; i--)
{
var att = Attribute.GetCustomAttribute(props[i], typeof(CustomAttribute), true) as CustomAttribute;
if (att != null)
propsFound.Add(props[i]);
else
propsNotFound.Add(props[i]);
}
Console.WriteLine("Found:");
foreach (var prop in propsFound)
{
Console.WriteLine(prop.Name + ": " + prop.GetValue(model, null));
}
Console.WriteLine(Environment.NewLine + "Not Found:");
foreach (var prop in propsNotFound)
{
Console.WriteLine(prop.Name + ": " + prop.GetValue(model, null));
}
Console.ReadKey();
}
}
このプログラムを .NET 3.5 で実行すると、LastName
プロパティの属性が見つからず、出力は次のようになります。
このプログラムを .NET 4.0 で実行すると、すべての属性が正しく検出されます。出力は次のとおりです。
これは単に .NET 3.5 に存在し、.NET 4.0 で修正されたバグですか? または、内部の抽象プロパティの属性にアクセスできるようにするために、私が見逃している他の微妙な点はありますか?
注: これは、具体的なクラスでオーバーライドされた場合にのみ、仮想プロパティにも当てはまるようです。