繁体   English   中英

方法参数(对象)不是类型列表C#

[英]Method Parameter (Object) not of Type List C#

嗨,我已经看过并需要一些帮助,我正在使用反射从类中获取值,这些类具有一个类似的名为“ 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

有没有这种方法,我尝试放置“类”和“哪里T:new()”

但似乎并没有解决问题

请帮忙

在您的GetName()方法中,您将需要测试对象类型,如果不是有效类型,则引发异常。

但是,这确实不是一种有效的方法。 您最好改用接口,这样您就不必担心不允许的类型,因为无效类型的数量可以达到无限的限制。

正如Daniel在对原始问题的评论中所指出的那样,让每个对象实现一个包含该属性的接口,并让您的方法将该接口作为其参数,这是限制它的最佳方法,例如:

public static void GetName(IPerson entity) { entity.Name = "Test"; }

只是在这里抛出另一个选项,因为您已经在使用反射,所以也可以在传入的对象上使用它来检测它是否具有name属性。

但是,这不会提供任何编译时异常,因此您必须在调用它时尝试/捕获它,或者让它返回一个空字符串而不是抛出异常(或其他东西)。

例如,如果只需要具有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);
}

你不能 如评论中所述, 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类的选项,但是如果您需要从某些东西中获取“名称”,我将无法想象它们的用途。

如果您走那条路线,则有两种选择:

  • 限制参数本身
  • 限制通用参数

那里的选择取决于方法的内容和返回类型,但我可能会选择前者。

public static string GetName<T>(IObjectWithName Object)
{
    return Object.Name;
}

作为示例,这并不是特别有趣,因此这是您将如何限制泛型的方法。

public static string GetName<T>(T Object)
    where T : IObjectWithName
{
    return Object.Name;
}

只要记住您的对象需要实现该接口即可,例如,您不能将DateTime传递给此方法,并且期望它可以工作。 如果您希望这样的“随机”输入,则可能还需要设置自己以接收集合类型。


我应该提一下,只是为了好的实践,给参数Object命名不是一个好习惯。 那是C#中的关键字(或更确切地说,是系统级别的类型)。 这样您就可以解决冲突了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM