C#,通用,访问 属性
C#, Generic, access to property
我在 C# 中使用通用 类,我想访问 Text
或对象的任何其他 属性,我该怎么做?
class Methods<T> where T : class
{
bool insertDocument(T content)
{
return client.search(content.Text);
}
}
而且我不想使用 Interface
你不能,你指定的唯一约束是 '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);
}
}
我觉得这是一个 XY problem 并且有更好的方法来实现这一点,但这里有一个可能的解决方案。
如果您希望特定属性在通用 class 中工作,您应该使用此属性创建一个接口并在使用的 class 中实现此接口,例如:
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。
你可以像这样使用动态:
class Methods
{
bool insertDocument(dynamic content)
{
return client.search(content.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);
}
然后按原样使用:
class ExampleClass
{
public string TestProperty {get;set;}
}
-
var example = new ExampleClass() { TestProperty = "hello"; }
bool result = insertDocument(example, e => e.TestProperty);
但您每次都需要指定选择器。至少这样你可以让你的代码保持强类型。
不过,我建议按照 Nikolaus 的回答使用界面。
我在 C# 中使用通用 类,我想访问 Text
或对象的任何其他 属性,我该怎么做?
class Methods<T> where T : class
{
bool insertDocument(T content)
{
return client.search(content.Text);
}
}
而且我不想使用 Interface
你不能,你指定的唯一约束是 '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);
}
}
我觉得这是一个 XY problem 并且有更好的方法来实现这一点,但这里有一个可能的解决方案。
如果您希望特定属性在通用 class 中工作,您应该使用此属性创建一个接口并在使用的 class 中实现此接口,例如:
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。 你可以像这样使用动态:
class Methods
{
bool insertDocument(dynamic content)
{
return client.search(content.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);
}
然后按原样使用:
class ExampleClass
{
public string TestProperty {get;set;}
}
-
var example = new ExampleClass() { TestProperty = "hello"; }
bool result = insertDocument(example, e => e.TestProperty);
但您每次都需要指定选择器。至少这样你可以让你的代码保持强类型。
不过,我建议按照 Nikolaus 的回答使用界面。