1

这可能是一个相当复杂的问题,但只是检查是否有答案。

考虑有两个大致如下所示的扩展方法(并且它们位于另一个我无法控制的程序集中):

public static class ExtensionMethods
{
    public static string ConversionA<T>(this T self) { /* .... */ }
    public static string ConversionB<T>(this T self) { /* .... */ }
} // eo class ExtensionMethods

我有一个在对象上使用此扩展方法的方法。理想情况下,我希望调用者明确指定要使用的转换函数,但在必要时默认使用它,所以我希望我能以某种方式将签名转换为Func<>

public static class Config
{
    public static T Read<T>(string fileName, Func<T, string> = ExtensionMethods.ConversionA<T>)
    {
    }
} // eo class Config

这可能吗?我知道这是一个很长的镜头:)

4

2 回答 2

4

这可能吗?

当然 - 你唯一不能做的就是有Func一个可选参数。可选参数的默认值必须是编译时常量。

但是,您可以通过重载来做到这一点:

public static T Read<T>(string fileName, Func<T, string> func) // non-optional parameter
{
    /* ... */
}

public static T Read<T>(string fileName)
{
    return Read<T>(fileName, ExtensionMethods.ConversionA<T>);
}
于 2013-04-12T19:02:39.923 回答
1

编辑

不幸的是,我错过了您要求定义默认方法的地方。这是不可能的。C# 明确禁止为任何非编译时常量分配默认参数。解决此问题的唯一方法是设置一些重载方法,例如:

public static T Read<T>(T input)
{
    Read(input, ExtensionMethods.ConversionA<T>);
}

public static T Read<T>(T input, Func<T, string> conversion)
{
    // Logic goes here
}

总而言之,它并没有那么糟糕。这是一点点额外的代码,它会让你得到你正在寻找的行为。

原来的

看起来你所拥有的应该基本上可以工作。您只需要指定它接受一个Func<T, string>. 您不能强制要求它始终ConversionA<T>or ConversionB<T>,但是这些类型签名中的任何一个都应该满足Func<T, string>.

例如(不知道你的转换方法做什么,我会自己编):

public static class Conversions
{
    public static string UpperString<T>(T self)
    {
        return self.ToString().ToUpper();
    }

    public static string LowerString<T>(T self)
    {
        return self.ToString().ToLower();
    }
}

public static T Read<T>(T input, Func<T, string> conversion)
{
    // Do-whatchya-do
}

void Main()
{
    Read<SomeObj>(new SomeObj(), Conversions.UpperString<SomeObj>);
    Read<SomeObj>(new SomeObj(), Conversions.LowerString<SomeObj>);
}

当您最终调用“Read”时,您只需要传递具有正确类型的泛型方法。因此,您可能需要稍微复制类型签名,但它应该可以正常工作。

它们是扩展方法并没有改变。任何扩展方法都可以显式地以非扩展格式使用。例如:

public static class Extensions 
{
    public static T SomeExtension<T>(this T value) { /* ... */ }
}

可以通过以下两种方式调用:

someT.SomeExtension();
Extensions.SomeExtension(someT);
于 2013-04-12T18:54:28.817 回答