简体   繁体   English

如何将链接的静态类名称和属性值转换为字符串?

[英]How to convert chained static class names and a property value to a string?

Context: Suppose one has the following class structure: 上下文:假设其中一个具有以下类结构:

public static class SomeStaticClass
{
    public static class SomeInnerStaticClass
    {
        public static readonly string SomeProperty = "someStringValue";
    }
}

Question: 题:

Is there an easy way to convert the reference SomeStaticClass.SomeInnerStaticClass.SomeProperty to string value of "SomeStaticClass.SomeInnerStaticClass.someStringValue"? 有没有一种简单的方法可以将引用SomeStaticClass.SomeInnerStaticClass.SomeProperty转换为字符串值“ SomeStaticClass.SomeInnerStaticClass.someStringValue”?

the first thing I posted was wrong because they were static types I wrote a little code and this works. 我发布的第一件事是错误的,因为它们是静态类型,因此我编写了一些代码,并且可以正常工作。

public static class A
{
    public static class B
    {
        public static string c
        {
            get
            {
                return "hi";
            }
        }
    }

}
class Program
{
    static void Main( string[] args )
    {

        Console.WriteLine(typeof(A.B).FullName.Replace("+",".") + "." +  A.B.c  ) ;
    }


}

Don't you just want: 你不只是想要:

public static class SClass
{
   public static class SInner
   {
       public static string Property = 
            (typeof(SInner)).DeclaringType.Name+ "." 
            + typeof(SInner).Name + "."
            + "value";
   }
}

Which would output SClass.SInner.Property.value 哪个将输出SClass.SInner.Property.value

If you wanted to automated it, you could put it in a while loop and exit once the parent type property IsNested is false. 如果要使其自动化,可以将其置于while循环中,并在父类型属性IsNested为false时退出。

You could use an expression: 您可以使用一个表达式:

namespace ConsoleApplication2
{
    using System;
    using System.Linq.Expressions;

    class Program
    {
        static void Main(string[] args)
        {
            string fullName = GetExpression(() => SomeClass.SomeProperty);

            Console.WriteLine(fullName);
        }

        public static string GetExpression<TProperty>(Expression<Func<TProperty>> expr)
        {
            string name = expr.Body.ToString();
            string value = expr.Compile().Invoke().ToString();

            name = name.Substring(0, name.LastIndexOf(".") + 1) + value;

            return name;
        }
    }

    public static class SomeClass
    {
        public static string SomeProperty = "Hello";
    }
}

Here's one more elaborate solution. 这是另一种精心设计的解决方案。 The method accepts a lambda expression denoting a property or a field. 该方法接受表示属性或字段的lambda表达式。 It the computes the value of the property or field and prepends it with names of all encapsulating classes. 它计算属性或字段的值,并为其加上所有封装类的名称。

I guess you want to have a type-safe method of producing some kind of structured / hierarchical identifiers encoded as a hierarchy of classes and properties or fields. 我想您想使用一种类型安全的方法来生成某种结构化的/分层的标识符,这些标识符编码为类,属性或字段的分层结构。 I've been using this approach for a few years and it helps prevent many hard-to-catch bugs caused by simple typos. 我使用这种方法已经有好几年了,它有助于防止许多由简单的错字引起的难以捕获的错误。

Code: 码:

public string GetStructuredName(Expression<Func<object>> nameObject)
{
    if (nameObject == null) throw new ArgumentNullException("nameObject");

    // find the expression denoting a property or a field
    MemberExpression member = null;
    switch (nameObject.Body.NodeType)
    {
        case ExpressionType.MemberAccess:
            member = (MemberExpression)nameObject.Body;
            break;
        case ExpressionType.Convert:
        case ExpressionType.ConvertChecked:
            member = ((UnaryExpression)nameObject.Body).Operand as MemberExpression;
            break;
    }
    if (member == null) throw new ArgumentNullException("nameObject");

    StringBuilder sb = new StringBuilder();

    // use the value of the member as the final component of the resulting name
    sb.Append(nameObject.Compile().DynamicInvoke());

    // use short names of embedded type names as components of the resulting name
    Type type = member.Member.DeclaringType;
    while (type != null && type != typeof(Object))
    {
        sb.Insert(0, ".");
        sb.Insert(0, type.Name);
        type = type.DeclaringType;
    }

    return sb.ToString();
}

Example: 例:

public class OuterContainer
{
    public class InnerContainer
    {
        public static string Property
        {
            get { return "value"; }
        }

        public static int Field = 10;
    }
}

GetStructuredName(() => OuterContainer.InnerContainer.Property)
GetStructuredName(() => OuterContainer.InnerContainer.Field)

The output will be: 输出将是:

"OuterContainer.InnerContainer.value"
"OuterContainer.InnerContainer.10"

I don't know about the nature of your input format, but you can do this with System.Linq.Expressions : 我不知道您的输入格式的性质,但是您可以使用System.Linq.Expressions做到这一点:

    Expression<Func<string>> expr = () =>
        SomeStaticClass.SomeInnerStaticClass.SomeProperty;

    var myResult = String.Concat(expr.Body, ".", expr.Compile().Invoke());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM