Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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#_Linq_Expression Trees - Fatal编程技术网

C# 访问运行时类型已知的对象的属性

C# 访问运行时类型已知的对象的属性,c#,linq,expression-trees,C#,Linq,Expression Trees,我有一个对象,其基本类型在编译时公开,但其运行时类型是内部的,并且出于所有实际目的,我无法在编译时访问该类型 但是,我希望能够在运行时访问其实例上的属性 我知道,如果在编译时不知道类型,我就无法创建类型化委托 访问此属性最有效的方式是什么?动力呕吐 假设这是一个文件:Hidden.cs internal class Hidden { public string SomeProp { get { .. } } } 我无法在代码Func someExpression=Express

我有一个对象,其基本类型在编译时公开,但其运行时类型是内部的,并且出于所有实际目的,我无法在编译时访问该类型

但是,我希望能够在运行时访问其实例上的属性

我知道,如果在编译时不知道类型,我就无法创建类型化委托

访问此属性最有效的方式是什么?动力呕吐

假设这是一个文件:Hidden.cs

 internal class Hidden
 {
     public string SomeProp { get { .. } }
 }
我无法在代码Func someExpression=Expression.Lambda>中键入以下内容


我只想确认,当我无法在编译时引用类型时,我的唯一选项是DynamicInvoke。

您可以始终使用
动态
委托,例如
函数
,t是您的返回类型。但请记住,动态调度是“慢”的,因为它使用了scènes后面的反射。DynamicVoke也做同样的事情,所以速度也一样慢

现在请记住,“慢”是非常相对的。与几乎是即时的静态调用相比,它的速度很慢,但这种微观优化在实际程序中几乎不值得注意

此外,为什么首先需要调用未知类型对象的属性?在我看来,这似乎是一个糟糕的设计决策的征兆。例如,考虑到相关类型从一个公共基类继承/实现相同的接口,突然您的问题消失。你会得到更好的表现作为奖励

编辑

一开始我没有意识到你想要访问一个你不应该看到的成员。那么反射是你唯一的希望。您还需要完全信任地运行代码。请记住,类的原始创建者决定不让您访问该成员,他可能有很好的理由。你不应该这样做,除非你真的不能这样做。

你可以创建
Func
,然后将
对象强制转换为
隐藏的
(你的类型),然后访问
SomeProp
。所有这些都可以通过以下表达式完成:

internal class Program
{
    private static Func<object, string> somePropFunc;
    private static void Main(string[] args)
    {
        //Create instance somehow
        Type type = typeof(Hidden);
        object hiddenInstance = Activator.CreateInstance(type);

        //Cache the delegate in static field, and use it any number of times
        somePropFunc = GetSomePropAccessorMethod();
        for (int i = 0; i < 100; i++)
        {
            // Access Hidden.SomeProp
            Console.WriteLine(somePropFunc(hiddenInstance));
        }
    }

    private static Func<object, string> GetSomePropAccessorMethod()
    {
        Type type = typeof(Hidden);
        PropertyInfo prop = type.GetProperty("SomeProp");
        var parameter = Expression.Parameter(typeof(object), "hidden");
        var castHidden = Expression.TypeAs(parameter, type);
        var propertyAccessor = Expression.Property(castHidden, prop);
        return Expression.Lambda<Func<object, string>>(propertyAccessor, parameter).Compile();
    }

}

internal class Hidden
{
    public string SomeProp
    {
        get
        {
            return "Some text";
        }
    }
}
内部类程序
{
私有静态函数somePropFunc;
私有静态void Main(字符串[]args)
{
//以某种方式创建实例
类型=类型(隐藏);
对象HiddeInstance=Activator.CreateInstance(类型);
//将委托缓存在静态字段中,并多次使用它
somePropFunc=GetSomePropAccessorMethod();
对于(int i=0;i<100;i++)
{
//访问隐藏的.SomeProp
Console.WriteLine(somePropFunc(hiddenInstance));
}
}
私有静态函数GetSomeProAccessorMethod()
{
类型=类型(隐藏);
PropertyInfo-prop=type.GetProperty(“SomeProp”);
var parameter=Expression.parameter(typeof(object),“hidden”);
var castHidden=Expression.TypeAs(参数,类型);
var propertyAccessor=Expression.Property(castHidden,prop);
返回表达式.Lambda(propertyAccessor,parameter).Compile();
}
}
隐藏的内部类
{
公共字符串SomeProp
{
得到
{
返回“一些文本”;
}
}
}

在控制台中打印“某些文本”100次。

为什么不能通过反射获取属性值?性能。我宁愿在表达式上使用DynamicInvoke。你知道编译时属性的返回类型是什么吗?如果不是,你将如何使用它?何时缓存
PropertyInfo
perfroman也不错。还要考虑<代码>动态< /代码>——我认为它比<代码>动态调用> <代码>更快——我已经做了一些性能测试,我会尝试找到结果报告。我知道属性的返回类型,但是我不知道它的类的类型。我将添加一些代码。长话短说,我需要访问内部类上的属性,而我不拥有这些代码。这是你需要做的事情之一…@user986697:这是一个非常糟糕的情况。如果您别无选择,请使用反射,缓存您使用的反射对象(通常是
PropertyInfo
),以减少开销,并祈祷库所有者永远不会更改其库的内部结构(这不应该是破坏性的更改,但会破坏您)。