Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.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#_Reflection - Fatal编程技术网

C# 属性是用户定义的吗?

C# 属性是用户定义的吗?,c#,reflection,C#,Reflection,如果属性是用户定义的,那么我现在如何在使用Type.GetProperties()获得的列表中找到它们 比如说 class test { public string propertyOne{get;set;} public string propertyTwo{get;set;} } 使用typeof(test).GetProperties()我得到了两个PropertyInfo,现在它们是用户定义的吗 关于上下文的信息,下面是应该通过的测试 [Test]

如果属性是用户定义的,那么我现在如何在使用Type.GetProperties()获得的列表中找到它们

比如说

class test
{
     public string propertyOne{get;set;}
     public string propertyTwo{get;set;}
}
使用
typeof(test).GetProperties()
我得到了两个PropertyInfo,现在它们是用户定义的吗

关于上下文的信息,下面是应该通过的测试

    [Test]
    public void GetFullNameScalarPropertiesTest()
    {
        // Act
        var properties = ReflectionHelper.GetFullNameScalarProperties(typeof(Parent));

        // Assert
        Assert.True(properties.Contains("PropertyOne"));
        Assert.True(properties.Contains("Child.PropertyTwo"));
        Assert.True(properties.Contains("Child.GrandChild.PropertyThree"));
        Assert.That(properties.Count, Is.EqualTo(3));
    }

    class Parent
    {
        public Parent()
        {
            Child = new Child();
        }

        public string PropertyOne { get; set; }
        public Child Child { get; set; }
    }

    class Child
    {
        public Child()
        {
            GrandChild = new GrandChild();
        }

        public string PropertyTwo { get; set; }
        public GrandChild GrandChild { get; set; }
    }

    class GrandChild
    {
        public string PropertyThree { get; set; }
    }
所以,在递归方法中,我获取属性并创建一个包含名称的列表

通过此测试的代码是

    public static IList<string> GetFullNameScalarProperties(Type type)
    {
        var lista = new List<string>();
        var path = string.Empty;
        var properties = type.GetProperties();

        foreach (var propertyInfo in properties)
            GetFullNameScalarProperties(propertyInfo, path, lista);

        return lista;
    }

    private static void GetFullNameScalarProperties(PropertyInfo propertyInfo, string path, ICollection<string> lista)
    {
        if (!string.IsNullOrEmpty(path))
            path += ".";

        path += propertyInfo.Name;

        if (propertyInfo.PropertyType.FullName != null)
            if (propertyInfo.PropertyType.FullName.StartsWith("System"))
            {
                lista.Add(path);
                return;
            }

        var properties = propertyInfo.PropertyType.GetProperties();

        foreach (var pi in properties)
            GetFullNameScalarProperties(pi, path, lista);
    }
公共静态IList GetFullNameScalarProperties(类型)
{
var lista=新列表();
var path=string.Empty;
var properties=type.GetProperties();
foreach(属性中的var propertyInfo)
GetFullNameScalarProperties(propertyInfo、path、lista);
返回列表a;
}
私有静态void GetFullNameScalarProperties(PropertyInfo PropertyInfo、字符串路径、ICollection列表A)
{
如果(!string.IsNullOrEmpty(路径))
路径+=”;
path+=propertyInfo.Name;
if(propertyInfo.PropertyType.FullName!=null)
if(propertyInfo.PropertyType.FullName.StartWith(“系统”))
{
添加(路径);
返回;
}
var properties=propertyInfo.PropertyType.GetProperties();
foreach(属性中的var pi)
GetFullNameScalarProperties(pi、path、lista);
}

没有什么比得上“用户定义”属性。要了解在继承层次结构中声明属性的类型,请查看。

不清楚“用户定义”是什么意思-您是否试图找出自动实现的属性和手工编写的属性之间的区别?如果是这样,自动实现的属性将在getter和setter上具有
[CompilerGenerated]
属性

using System;
using System.Runtime.CompilerServices;

class Program
{
    public int AutomaticallyImplemented { get; set; }
    public int HandWritten {
        get { return 0; }
        set {}
    }

    static void Main()
    {
        foreach (var property in typeof(Program).GetProperties())
        {
            bool auto = property.GetGetMethod().IsDefined
                (typeof(CompilerGeneratedAttribute), false);
            Console.WriteLine("{0}: {1}", property.Name, auto);
        }
    }
}

显然,您通常首先要检查是否有getter:)

如果要查找是否继承了属性,请将PropertyInfo.DeclaringType与您正在测试的类型进行比较

也许您想知道哪一个不是.NET Framework

您可以调用Type.GetProperties并使用LINQ迭代找到的属性,以便知道这些属性在类中的何处定义,以及在框架级别定义了哪些属性

正如其他人所说,您需要PropertyInfo.DeclaringType来了解某些属性的定义位置

如果项目的任何对象继承自某个基类,则可以执行以下操作:

someObject.GetType().GetProperties().Where(propInfo => propInfo.DeclaringType.IsSubclassOf(typeof(ProjectBaseType))

如果要获取这些非继承成员,请尝试并将
BindingFlags.DeclaredOnly
作为参数传递,如:

var properties  = typeof(test).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);

用户定义的?你的意思是非继承的还是非重写的?我会尽力澄清我需要什么你的更新仍然不是很清楚。但是,也有一些猜测:您正在寻找一种合理的方法来判断某个属性是否属于一组特定类型中的类型,以便在
GetFullNameScalarProperties
中决定是否深入到某个特定属性的类型并检查其属性。对吗?对,我只应该在为我创建属性类型时向下搜索。在父类中,我应该深入研究子属性,但没有属性我很想知道,但我相信这不是关于自动实现的访问器。@Matias:根据问题中缺少的信息,这是我能猜到的最接近的。完全不清楚OP的目的是什么。完全同意:)这只是一个评论@JonSkeet我只是在寻找同样的东西时遇到了这个问题。我认为他要求的(至少乍一看)是获得由开发人员定义的所有属性,而不是从对象继承的属性。我能想到的唯一方法是用一个自定义属性来装饰每个属性:/@sin美学:嗯
对象
没有任何属性,所以这不会是一个问题。使用新的反射API,您可以使用
type.GetTypeInfo().DeclaredProperties
。。。如果这是您的意思,那么将在该类中声明属性,而不是继承属性。如果继承有多个级别呢D