如何从不相关的类型中抽象操作?

时间:2017-04-18 09:34:17

标签: c# type-constraints

重新考虑我的问题后的评论。 尽管@Dogu Arslan提出了使用WriteData方法的确切示例的最佳解决方案,但问题标题中的问题实际上是由@InBetween和@Fabio解决的。 I. e。对于我使用WriteData方法的确切示例,最好将转换逻辑移出WriteData方法,但要从不相关类型中抽象逻辑,最好使用建议的重载。所以这三个答案对我都有帮助。

我已经阅读了以下类似的问题 - 12和其他问题 - 但在我的案例中没有找到合适的解决方案。

我的情况是:我有以下简单的方法。重要的部分是带注释的行和“源”参数。其余部分并不那么重要,仅用于表明问题标题中有“操作”。

void WriteData(
    int count, 
    int currentIndex, 
    List<byte> source, 
    StreamWriter sw, 
    string fileName)
{
    var countToWrite = count - currentIndex;

    if (countToWrite == 0)
        return;

    if (sw == null)
        sw = new StreamWriter(GetFullPath(fileName));

    //---------- Source's elements must be converted to string.
    var dataToWrite =
        source.GetRange(currentIndex, countToWrite)
        .Select(x => Convert.ToString(x));

    StringBuilder sb = new StringBuilder();

    foreach (var item in dataToWrite)
        sb.AppendLine(item);

    sw.Write(sb.ToString());
}

现在我希望“source”参数是带有字节,双精度或字符串的列表。我是否只用一次更改写了三份WriteData方法 - “源”中的列表类型?还是有更好的方法?

我尝试过类型约束,但要约束哪种类型?

我试图检查类型并抛出异常,如果它不在我的类型列表中(byte,double,string)。但异常只能在运行时工作,我希望它在编译时工作。

现在我必须将运行时类型检查限制为临时解决方案,但是,正如我之前提到的,它不适合透视。

3 个答案:

答案 0 :(得分:3)

为什么不在一个“隐藏”的实际解决方案中使用重载方法

public void WriteData(List<byte> source) { WriteData<byte>(source); }
public void WriteData(List<double> source) { WriteData<double>(source); }
public void WriteData(List<string> source) { WriteData<string>(source); }

private void WriteData<T>(List<T> source)
{
     // Your actual implementation
}

在私有方法中,您可以检查类型并在给出错误类型时抛出异常,以防您希望“保护”通过“错误”将私有方法公开。

答案 1 :(得分:2)

最好的解决方案是公开公开所需的重载,然后将实现委托给私有泛型方法:

public void WriteData( , , List<string> source, , ) { WriteData<string>(...); }
public void WriteData( , , List<byte> source, , ) { WriteData<byte>(...); }
public void WriteData( , , List<double> source, , ) { WriteData<double>(...); }

private void WriteData<T>( , , List<T> source, , ) 
{ 
    Debug.Assert(typeof(T).Equals(typeof(string)) ||
                 typeof(T).Equals(typeof(byte)) ||
                 typeof(T).Equals(typeof(double)));
    ...
}

答案 2 :(得分:1)

您可以做的一件事就是将字符串转换责任完全删除到另一个类。 StringConverter类,它将重载构造函数,这些构造函数将采用这些不同的输入类型将它们转换为字符串并提供返回字符串的方法。这样,即使您将来扩展您支持的类型,也不需要在您的示例中更改此方法,所有这些都将在您的字符串转换器类后面透明。检查也将是编译时,因为字符串转换器类将通过其构造函数获取输入。是的,这意味着每次你想要调用WriteData方法时,你需要实例化一个新的StringConverter对象,但C#不会提供你从架子上提出的级别上的类型约束。