首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在使用之前动态查找已使用的属性

在使用之前动态查找已使用的属性
EN

Stack Overflow用户
提问于 2014-01-04 00:03:13
回答 2查看 144关注 0票数 6

我正在寻找一个模式的优化,我所使用的动态表单应用程序。

我有一个存储库类,它有一个方法:

代码语言:javascript
运行
复制
public Entity Find(string objectId, List<string> includedProperties);

这将返回一个实体对象,其中只有在"includedProperties“中指定的字段,因为为所有目的构建整个对象在本例中是不必要的(有些实体拥有数百个属性)。

使用此存储库的示例域代码通常如下所示:

代码语言:javascript
运行
复制
var includedProperties = new List<string> {
    "FirstChildName" , 
    "FirstChildDob",
    "SecondChildName",
    "SecondChildDob"
}

然后,我获取一个对象:

代码语言:javascript
运行
复制
var person = repository.Find("123",includedProperties);

然后,我将属性与GetProperty(string propertyName)方法一起使用:

代码语言:javascript
运行
复制
var firstChildDob = person.GetProperty("FirstChildDob").AsDateTime();
...etc

这一切都工作良好,并符合应用程序的动态设计。但是,在获取对象之前,我总是需要分别声明“已使用”属性的列表,这让我感到恼火。

因此,我的问题是,通过反射或其他一些聪明之处,我是否可以通过使用“”方法在代码中稍后传递哪些参数来简化“包含属性”的构建?

使用上面的示例,我希望使用这样的助手(或类似的)构建列表:

代码语言:javascript
运行
复制
var includedProperties = HelperObject.GetFieldsUsedInCurrentCodeFile();

这将以某种方式提取传递给"GetProperty()“方法的字符串常量,从而节省了显式声明的需要。欢迎任何建议!

EN

回答 2

Stack Overflow用户

发布于 2014-01-04 00:37:56

事实上,不久前我也遇到了类似的问题;当时我能想到的最好的方法就是定义一个枚举,其中包含我想要在方法中使用的属性的名称。

使用这种方法,您可以通过遍历枚举来构建包含属性的列表。

这种方法与字符串相比有几个好处:

  1. 任何属性拼写问题或属性名称更改都在单个位置进行。
  2. 如果您正在使用Resharper这样的工具,则可以确定在枚举中何时有未使用的“属性”。

例如:

代码语言:javascript
运行
复制
    private enum PersonMethodProperties
    {
        FirstChildName,
        FirstChildDob,
        SecondChildName,
        SecondChildDob
    }

    private void PersonMethod()
    {
        var includedProperties = GetIncludePropertiesFromEnum(typeof(PersonMethodProperties));

        var person = repository.Find("123", includedProperties);

        var firstChildDob = person.GetProperty(PersonMethodProperties.FirstChildDob.ToString()).AsDateTime();
    }

    private List<string> GetIncludePropertiesFromEnum(Type propertiesEnumType)
    {
        var includedProperties = new List<string>();

        foreach (var name in Enum.GetNames(propertiesEnumType))
        {
            includedProperties.Add(name);
        }

        return includedProperties;
    }
票数 2
EN

Stack Overflow用户

发布于 2014-01-04 01:55:01

不幸的是,像尼特里克NDepend这样的代码分析工具无助于您,因为在当前版本中,它们不捕获方法的参数、名称和值。

但是,您可以使用罗斯林创建工具,该工具将分析解决方案,并生成一个类,其中包含一个包含已使用属性作为预构建事件的列表。查找对className.methodName的所有调用并返回其常量参数(在本例中为文本)的解决方案分析代码:

代码语言:javascript
运行
复制
static IEnumerable<string> GetMethodCallParametersValues(string solutionName, 
                                                         string className, 
                                                         string methodName)
{
    var workspace = Workspace.LoadSolution(solutionName);
    var solution = workspace.CurrentSolution;

    var createCommandList = new List<ISymbol>();
    var @class = solution.Projects.Select(s => s.GetCompilation()
                                                .GetTypeByMetadataName(className))
                                  .FirstOrDefault();
    var method = @class.GetMembers(methodName)
                        .AsList()
                        .Where(s => s.Kind == CommonSymbolKind.Method)
                        .FirstOrDefault();
    var locations = method.FindReferences(solution)
                          .SelectMany(r => r.Locations);

    List<string> result = new List<string>();
    foreach (var location in locations)
    {
        var model = location.Document.GetSemanticModel();
        var token = location.Location
                            .SourceTree
                            .GetRoot()
                            .FindToken(location.Location.SourceSpan.Start);
        var invocation = token.Parent.FirstAncestorOrSelf<InvocationExpressionSyntax>();
        var arguments = invocation.ArgumentList.Arguments;
        result.AddRange(arguments.Select(a => model.GetConstantValue(a.Expression).Value.ToString()));
    }
    return result.Distinct();
}

以及代码使用情况:

代码语言:javascript
运行
复制
var includedProperties = GetMethodCallParametersValues(@"c:\path\to\your.sln",
                                                       "SomeNamespace.SomeClass",
                                                       "GetProperty");

注意事项:由于Roslyn在解析解决方案文件中的小错误,您可能不得不在.sln文件中添加#来注释下面的行,以便它们看起来:

代码语言:javascript
运行
复制
# VisualStudioVersion = 12.0.21005.1
# MinimumVisualStudioVersion = 10.0.40219.1
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20914971

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档