Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从C中的泛型类型检索值#_C#_Generics_Reflection - Fatal编程技术网

C# 从C中的泛型类型检索值#

C# 从C中的泛型类型检索值#,c#,generics,reflection,C#,Generics,Reflection,我想获得一个泛型类型的值,传递给一个方法,如下所示: 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).ToStri

我想获得一个泛型类型的值,传递给一个方法,如下所示:

    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
    }
public abstract class Entity
{
    /// <summary>
    /// 
    /// </summary>
    public virtual string Segment { get; set; }
}
var value = info.GetValue(instanceOfEntity).ToString();
public virtual Domains.Vegetable.Result Get<T>(T entity) where T: Domains.Vegetable.Entity
{
    var type = typeof(T);
    var info = type.GetProperty("Segment");
    var value = info.GetValue(entity).ToString(); // throws exception

    // other stuff
}
public virtual Domains.vegeture.Result Get(),其中T:Domains.vegeture.Entity
{
var类型=类型(T);
var info=type.GetProperty(“段”);
var value=info.GetValue(type).ToString();//引发异常
//注意:我试过这个,效果不错,但感觉不对
//var entity=Activator.CreateInstance();
//var段=实体段;
//为简洁起见省略
}
名为Domains.vegeture.entity的实体如下所示:

    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
    }
public abstract class Entity
{
    /// <summary>
    /// 
    /// </summary>
    public virtual string Segment { get; set; }
}
var value = info.GetValue(instanceOfEntity).ToString();
public virtual Domains.Vegetable.Result Get<T>(T entity) where T: Domains.Vegetable.Entity
{
    var type = typeof(T);
    var info = type.GetProperty("Segment");
    var value = info.GetValue(entity).ToString(); // throws exception

    // other stuff
}
公共抽象类实体
{
/// 
/// 
/// 
公共虚拟字符串段{get;set;}
}
然后在我选择的任何对象上实现:

public class Tomato: Vegetable.Entity
{
    /// <summary>
    /// 
    /// </summary>
    public override string Segment => "/patch/seeded";
}
公共类番茄:蔬菜。实体
{
/// 
/// 
/// 
公共重写字符串段=>“/patch/seeded”;
}
因此,如果我调用我的方法:
Get()
,我希望在上面提到的方法中返回值“/patch/seed”


这可能吗?

失败的原因是
info
是一个
PropertyInfo
表示属于类型
实体
的名为
段的属性。(假设
实体
有这样一个属性。如果没有,则
信息
为空。)

为了检索该属性的值,您需要一个
实体的实例,如下所示:

    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
    }
public abstract class Entity
{
    /// <summary>
    /// 
    /// </summary>
    public virtual string Segment { get; set; }
}
var value = info.GetValue(instanceOfEntity).ToString();
public virtual Domains.Vegetable.Result Get<T>(T entity) where T: Domains.Vegetable.Entity
{
    var type = typeof(T);
    var info = type.GetProperty("Segment");
    var value = info.GetValue(entity).ToString(); // throws exception

    // other stuff
}
相反,您试图从
类型
读取
实体
属性

var value = info.GetValue(type).ToString();
您试图从另一个属性(
Type
)的实例中读取一个类(
Segment
)的属性,即使
Type
有一个名为
Segment
的属性,它也不会工作,因为
info
实体的属性,只能从
实体的实例中读取

在您的方法中没有
实体的实例。这就提出了一个问题,您试图从中读取属性的内容是什么?如果方法如下所示:

    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
    }
public abstract class Entity
{
    /// <summary>
    /// 
    /// </summary>
    public virtual string Segment { get; set; }
}
var value = info.GetValue(instanceOfEntity).ToString();
public virtual Domains.Vegetable.Result Get<T>(T entity) where T: Domains.Vegetable.Entity
{
    var type = typeof(T);
    var info = type.GetProperty("Segment");
    var value = info.GetValue(entity).ToString(); // throws exception

    // other stuff
}
public virtual Domains.player.Result Get(T entity),其中T:Domains.player.entity
{
var类型=类型(T);
var info=type.GetProperty(“段”);
var value=info.GetValue(entity.ToString();//引发异常
//其他东西
}
然后,假设属性存在,反射可能会工作。但如果该财产存在,您可以这样做:

public virtual Domains.Vegetable.Result Get<T>(T entity) where T: Domains.Vegetable.Entity
{
    var value = entity.Segment.ToString(); // throws exception

    // other stuff
}
public virtual Domains.player.Result Get(T entity),其中T:Domains.player.entity
{
var value=entity.Segment.ToString();//引发异常
//其他东西
}

但这不是重点。您遇到异常是因为您试图从另一个类的实例上的一个类读取属性。

正如大家告诉您的那样,异常是由于段是tomato实例的属性,而不是类型本身。正如您已经发现的,创建实例可以让您毫无例外地访问它。有两种方法可以让你达到你所期望的结果,但是如果不了解上下文,你就不可能知道哪种方法更好。这里真正的问题是属性是否必须是静态的

如果可以是静态的,只需从
实体
中删除
公共虚拟字符串段{get;set;}
,然后修改
公共重写字符串段=>“/patch/seeded”进入
公共静态字符串段=>“/patch/seeded”。这样你的代码就可以工作了

缺点是,您放松了从必须实现属性段的实体派生的每个类的约束(顺便说一句,我会将其标记为抽象而不是虚拟),这意味着您应该检查
info!=在方法中使用它之前,请使用null

如果您想/需要保持段虚拟/抽象,除了创建T的实例外,没有其他方法。这可以通过反射完成,就像在示例代码中一样,但最好通过这种方式在T上添加一个新的()约束:

public virtual Domains.Vegetable.Result Get<T>() where T: Domains.Vegetable.Entity, new()
{
    var entity = new T();
    var segment = entity.Segment;

    // omitted for brevity
}
public virtual Domains.vegeture.Result Get(),其中T:Domains.vegeture.Entity,new()
{
var entity=newt();
var段=实体段;
//为简洁起见省略
}

GetValue(type)
是问题所在<代码>类型
不是
番茄
的实例,它是
类型
的实例,该类型没有名为
的属性。为此,您需要将代码更改为
Get(T instance)
,因为您需要
T
的实例,您的
是一个实例属性。这意味着,类型
实体
(或派生类型)的对象/实例包含此属性的值,而不是类型本身。因此,查询/反映类型本身不能为这样的实例属性提供任何值。