Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/svn/5.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# 获取类和SetValue中属性的自定义属性_C#_.net_Reflection - Fatal编程技术网

C# 获取类和SetValue中属性的自定义属性

C# 获取类和SetValue中属性的自定义属性,c#,.net,reflection,C#,.net,Reflection,我只是想玩玩一些东西。我制作了一种OR/M类型的映射器,因为我使用的是反射,所以性能很慢。我如何加快速度或使用更好、更有效的方法 我有一个带有命名参数的自定义属性,并允许多个 然后,我使用反射来: 获取包含自定义属性装饰的属性 对于找到的每个属性,获取自定义属性数据 对于每个自定义属性数据,获取命名参数 然后我检查命名参数memberinfo名称,查看它是否与属性的相关命名参数匹配,如果匹配,则获取该命名参数的值集,最后从dataReader读取该命名参数值的数据,并使用.SetValue将

我只是想玩玩一些东西。我制作了一种OR/M类型的映射器,因为我使用的是反射,所以性能很慢。我如何加快速度或使用更好、更有效的方法

我有一个带有命名参数的自定义属性,并允许多个 然后,我使用反射来:

  • 获取包含自定义属性装饰的属性
  • 对于找到的每个属性,获取自定义属性数据
  • 对于每个自定义属性数据,获取命名参数
然后我检查命名参数memberinfo名称,查看它是否与属性的相关命名参数匹配,如果匹配,则获取该命名参数的值集,最后从dataReader读取该命名参数值的数据,并使用.SetValue将从读取器读取的值设置为属性

下面是一些代码(无论如何都不完整),希望有人能告诉我如何提高性能。 运行10000次(在此之前,对JIT EXERSIZE等进行初始调用)会得到以下平均时间:

3.79毫秒

手动操作(即从DB到DTO的硬编码映射):0.05ms

我知道这就像“另一个或/M”-但它不是那样的,它更是为了我的乐趣比什么

private T Populate<T>(IDataReader reader) where T : class, new()
{ 
   T val = new T();

            if (reader != null && !reader.IsClosed)
            {

                var propsWithSQLColumnNameAttributes = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).Where(prop => Attribute.IsDefined(prop, typeof(SQLColumnNameAttribute)) && prop.CanWrite && prop.GetSetMethod() != null);

                foreach (var currentProperty in propsWithSQLColumnNameAttributes)
                {   
                    foreach (var currentAttributeForProperty in currentProperty.GetCustomAttributesData())
                    {
                        string currentAttribParamValue = null;
                        foreach (var currentNamedArgument in currentAttributeForProperty.NamedArguments)
                        {
                            if (String.Equals(currentNamedArgument.MemberInfo.Name, SQLColumnNameAttribute.PropertyNames.DataColumnNamePropertyName, StringComparison.OrdinalIgnoreCase))
                            {
                                currentAttribParamValue = currentNamedArgument.TypedValue.Value == null ? null : currentNamedArgument.TypedValue.Value.ToString();


                                if (reader.DoesFieldExist(currentAttribParamValue))
                                {
                                    var dbRecordValue = reader[currentAttribParamValue] == DBNull.Value ? null : reader[currentAttribParamValue];

                                    currentProperty.SetValue(val, dbRecordValue, null);
                                }
                                break;
                            }
                        }
                    }
                }
            }

            return val;
}
private T-Populate(IDataReader阅读器),其中T:class,new()
{ 
T val=新的T();
if(reader!=null&&!reader.IsClosed)
{
var propsWithSQLColumnNameAttributes=typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)。其中(prop=>Attribute.IsDefined(prop,typeof(SQLColumnNameAttribute))&&prop.CanWrite&&prop.GetSetMethod()!=null);
foreach(propsWithSQLColumnNameAttributes中的var currentProperty)
{   
foreach(currentProperty.GetCustomAttributesData()中的var currentAttributeForProperty)
{
字符串currentAttribParamValue=null;
foreach(currentAttributeForProperty.NamedArguments中的变量CurrentNamedArguments)
{
if(String.Equals(currentNamedArgument.MemberInfo.Name、SQLColumnNameAttribute.PropertyNames.DataColumnNamePropertyName、StringComparison.OrdinalIgnoreCase))
{
currentAttribParamValue=currentNamedArgument.TypedValue.Value==null?null:currentNamedArgument.TypedValue.Value.ToString();
if(reader.DoesFieldExist(currentAttribParamValue))
{
var dbRecordValue=reader[currentAttribParamValue]==DBNull.Value?null:reader[currentAttribParamValue];
currentProperty.SetValue(val,dbRecordValue,null);
}
打破
}
}
}
}
}
返回val;
}
不是最好的代码,但无论如何,perf是这里的问题,我想知道如何改进它,或者使用不同的反射方法,或者使用的算法的顺序和种类是不正确的

非常感谢-我希望这个问题有意义。

看看这个页面,看看它是否对你有帮助。
它讨论了许多场景中的反射优化,一旦你想学习,这可能是一个很好的资源。

你是想通过学术练习获得性能,还是真的关心性能?我问,因为如果是后者,那么答案将非常不同;)谢谢你,乔希!我很关心演出。我想让它尽可能的快速和高效,作为一个例子,你可以检查存储库,或者感谢batagliao。它看起来很有趣,但仍然认为可能有点太多的代码来提高性能。但我想有时候你需要这么做。从阅读和获得的想法来看,似乎我可能需要在所讨论的类()和构造函数中创建一个缓存字典,查找有关自身的详细信息,并将propertyName和attribute param值存储在某种字典中。但是,如果我理解您所说的内容,就不会有访问缓存的方法,因为T是未知的。T可以称为typeof(T),所以字典中的键可以是Type。喜欢用词。谢谢巴塔利亚-很可能。问题是,由于对象“Type”比其他类型的类更臃肿,它显然会消耗更多的内存(即使它多几个字节或其他)。正如你所知道的,我是那些对记忆力和表现都很挑剔的人之一。好的,我将如何创建/存储此缓存?我的意思是它应该是一个静态字典,还是应该放在一个合适的缓存引擎中。缓存引擎的缺点是需要进行更多的维护和管理(即使用ASP.NET缓存)。它还必须是安全的,如果您正在制作类似于库的东西,您应该在库中缓存反射缓存。我会选择静态字典,当然是MT safe。缺点是,随着类型的反映,它的大小将不断增长,即使它们不再被使用。因此,您可以编写一个缓存类来包装词汇表并管理条目的过期。但是如果你不介意过期的话,那就很简单了。我在想这个!我想我也会使用并发字典。让我们看看它是如何发展的,如果我没有看到进步或情况变得更糟(我对此表示怀疑),我们将稍后发回