C#,Generic,访问财产

时间:2017-08-14 06:49:00

标签: c# generic-programming

我在C#中使用通用类,我想访问Text或对象的任何其他属性,我该怎么做?

class Methods<T> where T : class
{ 
    bool insertDocument(T content)
    {
        return client.search(content.Text);
    }
}

我不想使用Interface

4 个答案:

答案 0 :(得分:3)

这应该适合你。

class Methods<T> where T : class
{ 
    bool insertDocument(T content)
    {
        var textProperty = typeof(T).GetProperty("Text");
        var searchString = textProperty.GetValue(content).ToString();
        return client.search(searchString);
    }
}

答案 1 :(得分:2)

我觉得这是一个XY problem并且有更好的方法来实现这一点,但这里有一个可能的解决方案。

如果您希望特定属性在泛型类中工作,您应该使用此属性创建一个接口,并在使用的类中实现此接口,如:

class Methods<T> where T : class, ITexted
{ 
    bool insertDocument(T content)
    {
        return client.search(content.Text);
    }
}

public interface ITexted
{
    string Text {get; set;}
}

class UsedClass : ITexted
{
   public string Text { get; set; }
}

编辑:

如果您不想使用接口,则不需要通用类。 您可以像以下一样使用动态:

class Methods
{ 
    bool insertDocument(dynamic content)
    {
        return client.search(content.Text);
    }
}

答案 2 :(得分:1)

您无法指定作为唯一的约束条件。&#39; T&#39;应该是一个班级,而不是所有班级都有一个&#39;课程&#39;属性,因此您无法访问该属性。您只是滥用泛型(它们不是让单个函数与所有东西一起工作的方法,而是一种使单个函数与一个共享您想要的共同行为的对象类型子集一起工作的方法利用,在这里你没有指定一个子集,所以你最终得到一个相当无用的&#39; T&#39;类型)

答案 3 :(得分:1)

你可以这样做,虽然效率会更低:

using System.Linq.Expressions; // include this with your usings at the top of the file

bool insertDocument(T content, Expression<Func<T, string>> textField)
{
    string text = textField.Compile().Invoke(obj);
    return client.search(text);
}

然后使用它:

class ExampleClass
{
    public string TestProperty {get;set;}
}

-

var example = new ExampleClass() { TestProperty = "hello"; }
bool result = insertDocument(example, e => e.TestProperty);

但每次都需要指定选择器。至少通过这种方式,您可以保持代码的强类型。

我建议按照Nikolaus的回答使用界面。