仅使用反射获取基类属性,而不继承类
本文关键字:继承 属性 基类 反射 获取 | 更新日期: 2023-09-27 18:32:04
如何使用反射仅获取基类中的属性,而不是继承的类。
假设我的基类有一个虚拟方法,继承类重写了它。如果覆盖调用基。MyMethod() 然后在 base 中进行反射。MyMethod() 从两个类或仅继承类获取属性,具体取决于所使用的 BindingFlag。
有没有办法只能访问基类中的属性?
编辑:也许一些代码可以帮助解释为什么我想这样做。
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;
}
}
}
在填充 SaveParams 的 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
对象,您可以使用这些对象来构建过程调用,其中包含基于该类所需的任何数据。