Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为泛型类型编写扩展方法_C#_Generics_Methods_Extension Methods - Fatal编程技术网

C# 为泛型类型编写扩展方法

C# 为泛型类型编写扩展方法,c#,generics,methods,extension-methods,C#,Generics,Methods,Extension Methods,我需要编写一个扩展方法来替换字符串和StringBuilder中的字符。 我可以编写两种扩展方法,如: public static string ReplaceChar(this string value, string charToReplace) { return value.Replace(charToReplace, "_"); } public static StringBuilder ReplaceChar(this StringBuilder value, string

我需要编写一个扩展方法来替换字符串和StringBuilder中的字符。 我可以编写两种扩展方法,如:

public static string ReplaceChar(this string value, string charToReplace)
{
    return value.Replace(charToReplace, "_");
}

public static StringBuilder ReplaceChar(this StringBuilder value, string charToReplace)
{
    return new StringBuilder (value.ToString().Replace(charToReplace, "_"));
}
但我不知道是否有可能编写一个通用方法,如:

public static T ReplaceChar<T>(this T value, string charToReplace)
{
    return new T(value.ToString().Replace(charToReplace, "_"));
}

在这种情况下,我有一个错误:T没有新的构造函数。您的方法有两个问题。给您带来错误的是,如果您想新建约束,T需要有一个新约束:

这是不可能的,这是泛型的一个限制,你不能对newstring或任何类似的东西进行约束。这可能是一个不错的功能,您可以建议:-

所以关于你的具体问题,你不可能做你想做的事情:string和StringBuilder是两种完全不同的类型,它们不共享任何有用的接口,也没有任何有用的约束,可以让你在泛型方法中同时使用这两种方法,不管是不是扩展方法。对于这种特定情况,您需要实现两种扩展方法

关于问题标题写一个泛型类型的扩展方法,是的,有可能有这样一个泛型扩展方法,它适用于所有满足T约束的类型。没有接口之类的特定约束没有多大意义,因为你基本上无法对对象做任何事。。。如果您不使用约束,那么最好创建对象的扩展方法

我想到的唯一一件可能有用的事情是,如果试图创建一个类型的扩展方法,该扩展方法要求将相同的类型作为附加参数传递。。。比如:

public static int Compare<T>(this T value, T value2)
    where T : IComparable
{
    return value.CompareTo(value2);
}

您希望确保第二个参数与扩展对象的类型相同。

您的方法存在两个问题。给您带来错误的是,如果您想新建约束,T需要有一个新约束:

这是不可能的,这是泛型的一个限制,你不能对newstring或任何类似的东西进行约束。这可能是一个不错的功能,您可以建议:-

所以关于你的具体问题,你不可能做你想做的事情:string和StringBuilder是两种完全不同的类型,它们不共享任何有用的接口,也没有任何有用的约束,可以让你在泛型方法中同时使用这两种方法,不管是不是扩展方法。对于这种特定情况,您需要实现两种扩展方法

关于问题标题写一个泛型类型的扩展方法,是的,有可能有这样一个泛型扩展方法,它适用于所有满足T约束的类型。没有接口之类的特定约束没有多大意义,因为你基本上无法对对象做任何事。。。如果您不使用约束,那么最好创建对象的扩展方法

我想到的唯一一件可能有用的事情是,如果试图创建一个类型的扩展方法,该扩展方法要求将相同的类型作为附加参数传递。。。比如:

public static int Compare<T>(this T value, T value2)
    where T : IComparable
{
    return value.CompareTo(value2);
}

您希望确保第二个参数与扩展对象的类型相同。

不幸的是,没有简单的方法可以实现这一点

不能使用任何从泛型获取参数的构造函数。 它们仅限于新的T’


您可以使用反射来解决这个问题,但它会使代码难以理解并阻止编译时类型检查。

不幸的是,没有简单的方法可以实现这一点

不能使用任何从泛型获取参数的构造函数。 它们仅限于新的T’


您可以使用反射解决这个问题,但它会使代码难以理解,并阻止编译时类型检查。

这是一个非常糟糕的主意。您希望以相同的方式使用不可变类型和可变类型。StringBuilder的唯一作用是为字符串操作提供更好的速度性能。您的StringBuilder扩展方法既糟糕又无用

很糟糕,因为它创建了两个对象,并且违反了StringBuilder的理念。 因为StringBuilder已经有了替换方法,所以没有用
这是一个非常糟糕的主意。您希望以相同的方式使用不可变类型和可变类型。StringBuilder的唯一作用是为字符串操作提供更好的速度性能。您的StringBuilder扩展方法既糟糕又无用

很糟糕,因为它创建了两个对象,并且违反了StringBuilder的理念。 因为StringBuilder已经有了替换方法,所以没有用
尝试公共静态T replaceChart此T值,字符串charToReplace其中T:new您应该使用StringBuilder.Replace,而不是创建一个中间字符串来进行替换。如果这样做,就不会剩下泛型操作,因为您只是依赖于接收器上的方法的存在。@Harry-这不起作用,因为代码试图调用参数化的con

结构者。新约束要求该类型具有无参数构造函数。我支持Lee的评论。字符串是不可变的,因此ReplaceChar返回新字符串是预期的行为。然而,大多数字符串生成器方法都是由于其副作用而被调用的,即修改调用它们的字符串生成器,因此ReplaceCharacter返回新的字符串生成器肯定不是我所期望的。它应该返回调用它的字符串生成器。设计为只处理两种具体类型的泛型方法是个坏主意。通用方法应该是。。。嗯,…泛型,也就是说,在理论上与任何类型的工作都是无限的,符合提供的约束条件。这里正确的解决方案是重载ReplaceChar。也就是说,我同意Olivier的观点,您的StringBuilder扩展方法很糟糕。请尝试使用公共静态T replaceChart此T值,string charToReplace Where T:new您应该使用StringBuilder.Replace,而不是创建一个中间字符串来进行替换。如果这样做,就不会剩下泛型操作,因为您只是依赖于接收器上的方法的存在。@Harry-这不起作用,因为代码试图调用参数化构造函数。新约束要求该类型具有无参数构造函数。我支持Lee的评论。字符串是不可变的,因此ReplaceChar返回新字符串是预期的行为。然而,大多数字符串生成器方法都是由于其副作用而被调用的,即修改调用它们的字符串生成器,因此ReplaceCharacter返回新的字符串生成器肯定不是我所期望的。它应该返回调用它的字符串生成器。设计为只处理两种具体类型的泛型方法是个坏主意。通用方法应该是。。。嗯,…泛型,也就是说,在理论上与任何类型的工作都是无限的,符合提供的约束条件。这里正确的解决方案是重载ReplaceChar。也就是说,我同意Olivier的观点,您的StringBuilder扩展方法非常糟糕。我的意思是您可以尝试使用反射来获取带参数的构造函数。如果你要这么做,使用泛型没有多大意义。。。只是对objectI进行扩展,这意味着您可以尝试使用反射来获取带有参数的构造函数。如果你要这么做,使用泛型没有多大意义。。。只是对objectJcl进行一个扩展,你告诉我有可能这样做吗?…如何?@Cap_72不,你想要的完全不可能,因为string和StringBuilder是两种完全不同且不相关的类型,没有任何有用的约束将匹配这两种类型。我想说的是,泛型类型的扩展是可能的,而不是你想要的那种。如果我不清楚,让你觉得这是可能的话,我很抱歉。我已编辑以添加进一步的注释SCL您是否告诉我有可能这样做?…如何?@Cap_72不,完全是您想要的,是不可能的,因为string和StringBuilder是两种完全不同且不相关的类型,没有任何有用的约束将匹配这两种类型。我想说的是,泛型类型的扩展是可能的,而不是你想要的那种。如果我不清楚,让你觉得这是可能的话,我很抱歉。我已编辑以添加更多评论
public static int Compare<T>(this T value, T value2)
    where T : IComparable
{
    return value.CompareTo(value2);
}