[英]Only get base class properties, not inheriting class, using reflection
如何使用反射僅獲取基類中的屬性,而不獲取繼承的類中的屬性。
說我的基類有一個虛擬方法,繼承類覆蓋它。 如果重寫調用base.MyMethod(),則base.MyMethod()中的反射會從這兩個類或僅從繼承類中獲取屬性,具體取決於所使用的BindingFlags。
有沒有辦法我只能訪問基類中的屬性?
編輯:也許一些代碼將有助於解釋為什么我要這樣做。
internal static void Save(DataTransactionAccess data, string sproc, object obj)
{
if (checkMandatoryProperties(obj))
{
saveToDatabase(data, sproc, obj);
}
}
private static void saveToDatabase(DataTransactionAccess data, string sproc, object obj)
{
List<object> paramList;
PropertyInfo idProperty;
populateSaveParams(out paramList, out idProperty, obj);
if (idProperty != null)
{
int id = data.ExecuteINTProcedure(sproc, paramList.ToArray());
idProperty.SetValue(obj, id, null);
}
else
{
data.ExecuteProcedure(sproc, paramList.ToArray());
}
}
private static void populateSaveParams(out List<object> paramList, out PropertyInfo idProperty, object obj)
{
paramList = new List<object>();
idProperty = null;
foreach (PropertyInfo info in obj.GetType().GetProperties())
{
if (info.GetCustomAttributes(typeof(SaveProperty), true).Length > 0)
{
paramList.Add("@" + info.Name);
paramList.Add(info.GetValue(obj, null));
}
if (info.GetCustomAttributes(typeof(SaveReturnIDProperty), true).Length > 0)
{
idProperty = info;
}
}
}
我需要在populateSaveParams的foreach循環中獲取調用Save的obj中的類的屬性,而不是其繼承的任何類或其子類的屬性。
希望這使事情變得更清楚。
我遇到了一個場景,在該場景中,我需要一種僅基於基類屬性執行決策的方法。
因此,我過濾了實例的屬性,可以通過以下兩種方法之一來完成,如下所示:
使用Type
上的BaseType
屬性,然后調用GetProperties
方法,
var baseType = instance.GetType().BaseType;
var properties = baseType.GetProperties();
使用DeclaringType
屬性檢查它是來自基類還是派生類,
var type = instance.GetType();
var properties = type.GetProperties();
// properties = properties.Where(p => p.DeclaringType.FullName == typeof(SomeClass).FullName).ToArray();
properties = properties.Where(p => p.DeclaringType.FullName == type.BaseType.FullName).ToArray();
下面的代碼片段檢索基類屬性並將其寫入輸出流。 這是編譯C#在線鏈接
using System;
using System.Linq;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
// Employee (derived class) - Person (base class)
var employee = new Employee
{
Company = "Stack Overflow",
Designation = "Community Manager",
FirstName = "Josh",
LastName = "Heyer"
};
var baseType = employee.GetType().BaseType;
var properties = baseType.GetProperties();
var method = baseType.GetMethod("Print");
for (var i = 0; i < properties.Count(); i++)
{
Console.WriteLine(properties[i].Name);
}
Console.WriteLine();
method.Invoke(employee, null);
}
}
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual void Print()
{
Console.WriteLine("Name: {0} {1}", FirstName, LastName);
}
}
public class Employee : Person
{
public string Company { get; set; }
public string Designation { get; set; }
public override void Print()
{
base.Print();
Console.WriteLine("Employment Details: {0} {1}", Company, Designation);
}
}
}
在我看來,似乎需要進行一些重組。 任何實現接口的操作都會返回一組保存操作:
public interface ISomeInterface
{
IEnumerable<SaveStep> SaveData();
}
public class SomeClass : SomeBaseClass, ISomeInterface
{
public virtual IEnumerable<SaveStep> SaveData()
{
foreach(var item in base.SaveData())
yield return item;
yield return new SaveStep { ... }
}
}
然后,您的擴展方法(或實際上是任何調用程序)只需要調用SaveData
方法,就可以獲取一組SaveStep
對象, SaveStep
對象可用於根據該類想要的內容來構造帶有數據的過程調用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.