从通用对象中获取价值(可能不存在)

时间:2011-06-24 13:37:26

标签: c#

我需要一个列表,可以查询特定属性的项目,如果该属性具有正确的值,则返回该项目。我想出了以下内容:

public class MyList<T>
{
    public T[] items;

    public Get( string name )
    {
        foreach( T item in items )
        {
            if( item.name == name )
                return item;
        }
        return null; // if not found
    }
}

上面给出了编译错误,因为类型T不一定具有我正在检查的属性。这是有道理的,但我需要做些什么才能获得这种行为。请注意,我不能将词典用于超出本问题范围的原因,尽管词典对于我正在尝试重新创建的词汇是必不可少的。

5 个答案:

答案 0 :(得分:4)

在函数定义后面添加约束

public class MyList<T> where T : YourObjectThatHasNameProperty

答案 1 :(得分:2)

您可以像这样使用反射:

public static Object TryGetPropertyValue(Object fromThis, String propertyName, Boolean isStatic)
{
    // Get Type
    Type baseType = fromThis.GetType();

    // Get additional binding flags
    BindingFlags addFlag = BindingFlags.Instance;
    if(isStatic)
        addFlag = BindingFlags.Static;

    // Get PropertyInfo
    PropertyInfo info = baseType.GetProperty(propertyName, BindingFlags.Public | addFlag);

    // Check if we found the Property and if we can read it
    if(info == null || !info.CanRead)
            return null;

    // Return the value
    return info.GetValue(fromThis, null);
}

编辑:如果函数返回null,您可以假设所提供的对象上不存在该属性。

答案 2 :(得分:1)

您可以使用反射来查看T是否具有该属性:

Type type = item.GetType();
bool hasproperty = type.GetProperties().Where(p => p.Name.Equals("name")).Any();

答案 3 :(得分:0)

您需要将T限制为具有此类属性的类型:

interface INamed { 
    string Name { get; }
}

public class MyList<T> where T : INamed 

    public T[] items;

    public T Get( string name ) {
        foreach( T item in items ) {
        if( item.Name == name )
            return item;
        }
        return null; // if not found
    }
}

然后,例如,

class Foo : INamed {
    private readonly string name;
    private readonly int foo;
    public string Name { get { return this.name; } } 
    public Foo(string name, int foo) {
        this.name = name; 
        this.foo = foo;
    }
}

MyList<Foo> list = // some instance of MyList<Foo>
Foo alice = list.Get("Alice");

答案 4 :(得分:0)

使用通用约束。

public interface IHasName
{
    string name;
}    

public class MyList<T> where T : IHasName
{
    public T[] items;

    public Get( string name )
    {
        foreach( T item in items )
        {
            if( item.name == name )
                return item;
        }
        return null; // if not found
    }
}