您好我已经看过并需要一些帮助,我使用反射从类中获取值,这些类有一个类似的名称“Name” 我有一个方法
public static void GetName<T>(T Object)
{
xxxxxxx
}
现在,用户将使用此类方法
var User = .....
var name = GetName(User);
如何仅限用于类对象,因为我想阻止使用List和其他类型 前
List<SystemUsers> users = .....
var name = GetName(users) ... this should not be allowable
有没有这样的方法,我尝试放置“class”和“where T:new()”
但它似乎没有做到这一点
请帮助
答案 0 :(得分:1)
在GetName()方法中,您需要测试对象类型,如果它不是有效类型,则抛出异常。
但是,这并不是一种有效的方法。您可能最好使用界面,这样您就不必担心您不允许的类型 - 因为无效类型的数量可能达到无限限制。
答案 1 :(得分:1)
正如Daniel在原始问题的评论中所述,让每个对象实现一个包含属性的接口,并让您的方法将该接口作为其参数将是限制它的最佳方式,例如:
public static void GetName(IPerson entity) { entity.Name = "Test"; }
答案 2 :(得分:1)
只是为了抛出另一个选项,因为你已经在使用反射,你也可以在传入的对象上使用它来检测它是否有一个名称属性。
但是,这不会给出任何编译时异常,所以你在调用它时必须尝试/ catch,或者让它返回一个空字符串而不是抛出异常(或其他东西......)。 / p>
例如,如果您只想要具有Name
属性的对象,则可以执行以下操作:
private static string GetName<T>(T input)
{
var nameProperty =
typeof (T)
.GetProperties()
.FirstOrDefault(propInfo =>
propInfo.Name.Equals("Name", StringComparison.OrdinalIgnoreCase));
if (nameProperty == null)
{
throw new InvalidOperationException(
"The input type does not have a name property");
}
return (string) nameProperty.GetValue(input);
}
答案 3 :(得分:0)
你不能。正如评论中所述,List<>
是一个类。将其限制为类将包括它。
这是一个不幸的情况,你可能只需依靠调用代码时使用的契约,并为无效的参数抛出异常。
public static string GetName<T>(T Object)
{
if(Object is IEnumerable) throw new ArgumentException();
xxxxxxx
}
另一种选择可能是添加一个IEnumerable
的重载。它不是很漂亮,你可能不需要它,但至少编译器会选择它并返回适当的东西。
public static IEnumerable<string> GetName<T>(IEnumerable<T> Objects)
{
return Objects.Select(GetName);
}
但要小心,因为有时候很难预测(或者更确切地说,要记住预测)将会调用哪一个。
List<int> ints = new List<int>();
GetName(ints); // calls the IEnumerable version
object intsObj = (object)ints;
GetName(intsObj); // calls the non-IEnumerable version.
但更一般地说,听起来你可能会在这里建立一个不太理想的合同。如果您使用未经过滤的仿制药做这样的事情,您可能也希望能够处理其中的集合,事实上我不确定为什么您不能至。他们像其他任何东西一样反对。
如果 试图限制它,您可能需要一个接口或基类,必须从该接口或基类继承传递给此方法的所有对象。这将大大减少你传递.NET类的选择,但我无法想象如果你需要得到一个&#34;名称&#34;来自某事。
如果你去那条路线,你有两个选择:
那里的选择取决于方法的内容和返回类型,但我可能会选择前者。
public static string GetName<T>(IObjectWithName Object)
{
return Object.Name;
}
但是,作为一个例子,这并不是特别有趣,所以这就是你如何限制泛型。
public static string GetName<T>(T Object)
where T : IObjectWithName
{
return Object.Name;
}
请记住,您的对象需要实现该界面 - 例如,您无法将DateTime
传递给此方法并期望它能够正常工作。如果你期望&#34;随机&#34;像这样输入,你可能需要自己设置接收集合类型。
我应该提一下,仅仅为了良好的练习,命名参数Object
不是一个好习惯。这是C#中的关键字(或者说是系统级类型)。所以你最终可能会遇到冲突。