1
public static object GetObject(int x)
{
    return new object { };
}
public static object GetObject(string x)
{
    return new object { };
}
public static void ProcessObject<T>(T x) where T : int, string <= got error here: 
{
    object o = GetObject(x);
}

出现错误“用作约束的类型必须是接口、非密封类或类型参数。”

我如何重写代码以使其在不写入ProcessObject(int x)ProcessObject(string x)两次的情况下工作?

4

5 回答 5

3

因此,您现在拥有的(根据接受的答案和您的评论)是:

public static void ProcessObject<T>(T x)
{
    object o;
    if (typeof(T) == typeof(int))
        o = GetObject((int)(object)x);
    else if (typeof(T) == typeof(string))
        o = GetObject((string)(object)x);
    else
        throw new Exception();
    // do stuff with o
}

我建议公开intstring重载,但为了防止代码重复,请在内部调用另一种方法:

public static void ProcessObject(int x)
{
    ProcessObject(GetObject(x));
}
public static void ProcessObject(string x)
{
    ProcessObject(GetObject(x));
}
private static void ProcessObject(object o)
{
    // do stuff with o
}

这使您的public方法的输入值清晰:int并且string是唯一可接受的类型,同时仍然不复制您的实际逻辑(// do stuff with o)。

您可能不喜欢这两个公共ProcessObject方法是彼此重复的,(无论如何表面上;在幕后,它们调用了两个不同GetObject的重载),但我认为这是最好的选择。

于 2012-08-04T12:28:34.247 回答
2

你不能做你想做的事:首先,不可能在一个通用约束中列出几个类;其次,您可以放入约束中的类型必须是您可以继承它(或者如果它是接口则实现它)的类型。两者int都未通过string此检查。在这种情况下,最好使用两个单独的重载。

于 2012-08-04T12:00:07.730 回答
1

一般来说,如果您的对象根据泛型类型参数做出不同的反应,那么在这种情况下您可能不应该使用泛型。泛型非常适合您希望始终做同样事情的情况,无论实际使用什么类型。

因此,泛型约束只允许您为类型参数列出一个基类。传递给相应类型参数的任何实际类型都是给定继承层次结构的一部分,从您指定的基类开始,因此您的类的用户可以指定与基类或其任何子类匹配的任何类型。

同时,作为泛型类的作者,您可以放心地假设指定的类型(至少)具有约束所指示的基类的接口。因此,您可以访问基类的任何成员。

如果你想允许stringor int,想象一下可能是什么成员。两者都直接来自System.Object,因此限制没有意义,因为它没有限制;每种类型都派生自System.Object.

总而言之,如果你真的想区别对待stringint这绝对是提供两个重载而不是一个泛型类的情况。

于 2012-08-04T12:14:28.150 回答
1

在 C# 中不可能查看Constraints on Type Parameters。尝试使用动态

于 2012-08-04T12:04:44.170 回答
1

只需删除where部分

public static void ProcessObject<T>(T x) 
{
    object o = GetObject(x);
}

而且也不要object在你的其他方法中使用,而是使用T

于 2012-08-04T11:59:53.470 回答