I want to get the value of a generic type, passed through to a method, which looks like this:
public virtual Domains.Vegetable.Result Get<T>() where T: Domains.Vegetable.Entity
{
var type = typeof(T);
var info = type.GetProperty("Segment");
var value = info.GetValue(type).ToString(); // throws exception
// NOTE: I have tried this, which works, but this feels wrong
//var entity = Activator.CreateInstance<T>();
//var segment = entity.Segment;
// omitted for brevity
}
The entity called Domains.Vegetable.Entity looks something like this:
public abstract class Entity
{
/// <summary>
///
/// </summary>
public virtual string Segment { get; set; }
}
which is then implemented on any object of my choosing:
public class Tomato: Vegetable.Entity
{
/// <summary>
///
/// </summary>
public override string Segment => "/patch/seeded";
}
So, if I call my method: Get<Tomato>()
, I'm expecting to get the value "/patch/seeded" back in the method mentioned above.
Is this even possible?
答案 0 :(得分:1)
失败的原因是info
是一个PropertyInfo
,代表一个名为Segment
的属性,属于类型Entity
。 (假设Entity
具有这样的属性。如果没有,info
为空。)
要检索该属性的值,您需要一个Entity
的实例,如下所示:
var value = info.GetValue(instanceOfEntity).ToString();
相反,您尝试从Segment
中读取Entity
的{{1}}属性。
Type
您正试图从另一个属性(var value = info.GetValue(type).ToString();
的实例中读取一个类(Segment
)的属性。即使Type
具有名为{{1}的属性},这是行不通的,因为Type
是Segment
的属性,只能从info
的实例读取。
在您的方法中,没有Entity
的实例。这就提出了一个问题,您想从中读取财产吗?如果该方法看起来像这样:
Entity
然后,假设该属性存在,则反射可能会起作用。但是,如果该属性存在,则只需执行以下操作:
Entity
但这是重点。之所以会出现异常,是因为您试图从另一个类的实例的一个类中读取属性。
答案 1 :(得分:0)
正如每个人都告诉您的,例外是由于段是西红柿实例的属性,而不是类型本身的属性。正如您已经发现的那样,创建实例使您可以毫无例外地访问它。您可以通过两种方法来获得期望的结果,但是在不了解上下文的情况下无法分辨出哪个更好。这里真正的问题是属性是否必须是静态的。
如果它可以是静态的,只需从public virtual string Segment { get; set; }
中删除Entity
并将public override string Segment => "/patch/seeded";
修改为public static string Segment => "/patch/seeded";
。这样,您的代码即可工作。
缺点是事实是,您必须放宽对每个从Entity派生的类的约束,必须执行一个属性Segment(顺便说一句,我将其标记为abstract而不是virtual),这意味着您应该检查{{1 }},然后在您的方法中使用它。
如果您想/需要保持您的Segment虚拟/抽象,除了创建T的实例,别无其他方法。可以像示例代码中那样通过反射来完成,但是最好添加一个new( )以这种方式约束T:
info != null