C#,通用,访问属性

C#,通用,访问属性,c#,generic-programming,C#,Generic Programming,我在C#中使用泛型类,我想访问文本或对象的任何其他属性,我该怎么做 class Methods<T> where T : class { bool insertDocument(T content) { return client.search(content.Text); } } class方法,其中T:class { bool插入文档(T内容) { 返回client.search(content.Text); } } 我不想使用接口

我在C#中使用泛型类,我想访问
文本
或对象的任何其他属性,我该怎么做

class Methods<T> where T : class
{ 
    bool insertDocument(T content)
    {
        return client.search(content.Text);
    }
}
class方法,其中T:class
{ 
bool插入文档(T内容)
{
返回client.search(content.Text);
}
}

我不想使用
接口

您不能这样做,因为您指定的唯一约束是“t”应该是“class”,并非所有类都有“Text”属性,因此您无法访问该属性。您只是误用了泛型(它们不是让单个函数处理所有事情的方法,而是让单个函数处理共享您想要利用的常见行为的对象类型子集的方法,这里您没有指定子集,因此您最终得到了一个相当无用的“T”类型)

您不能,您正在指定“T”应为“class”的唯一约束,并非所有类都具有“Text”属性,因此无法访问该属性。您只是误用了泛型(它们不是让单个函数处理所有事情的方法,而是让单个函数处理共享您想要利用的常见行为的对象类型子集的方法,这里您没有指定子集,因此您最终得到了一个相当无用的“T”类型)

这应该适合您

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);
    }
}
class方法,其中T:class
{ 
bool插入文档(T内容)
{
var textProperty=typeof(T).GetProperty(“文本”);
var searchString=textProperty.GetValue(content.ToString();
返回client.search(searchString);
}
}

这应该适合您

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);
    }
}
class方法,其中T:class
{ 
bool插入文档(T内容)
{
var textProperty=typeof(T).GetProperty(“文本”);
var searchString=textProperty.GetValue(content.ToString();
返回client.search(searchString);
}
}
我觉得这是一个很好的解决方案,有更好的方法来实现这一点,但这里有一个可能的解决方案

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

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<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; }
}

您可以这样做,但效率会更低:

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);
}
-

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


不过,我建议按照尼古拉斯的回答使用界面。

您可以这样做,但效率会更低:

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);
}
-

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


然而,我建议按照尼古拉斯的回答使用一个界面。

那么这里的
客户端是什么?如何声明
索引
方法?这在泛型类中吗?这里丢失了太多信息,无法帮助你。是否存在声明
Id
属性的公共接口或抽象类?除非您尚未解释在某些基类或接口中是否声明了
Text
属性。(顺便说一句,我强烈建议您开始遵循.NET命名约定。)如果我调用
new Methods().insertDocument(new object())
,您预计会发生什么
其中T:ClassNameWithTextProperty
@easa您需要一个接口、抽象类或基类,您可以在泛型where子句中对其进行限制。否则,编译器无法知道您的方法可从此对象访问。或者你使用动态编程,大多数时候不需要的和丑陋的东西。那么什么是
客户机
?如何声明
索引
方法?这在泛型类中吗?这里丢失了太多信息,无法帮助你。是否存在声明
Id
属性的公共接口或抽象类?除非您尚未解释在某些基类或接口中是否声明了
Text
属性。(顺便说一句,我强烈建议您开始遵循.NET命名约定。)如果我调用
new Methods().insertDocument(new object())
,您预计会发生什么或
其中T:ClassNameWithTextProperty
@easa您需要一个接口、抽象类或基类,您可以在泛型where子句中对其进行限制。否则,编译器无法知道您的方法可从此对象访问。或者你去动态规划什么是不需要的和丑陋的大多数时候。