C# 关于如何清理此API的建议

C# 关于如何清理此API的建议,c#,design-patterns,api,oop,C#,Design Patterns,Api,Oop,为了一个有趣的项目,我正在尝试实现BitTorrent规范,现在我正在处理其中的BEncoding部分 编码基本上可以从int/string/dictionary->string进行编码传输。我已经将所有不同的编码编写/测试/用作重载的Encode(…)方法,并将各个解码方法编写/测试/用作DecodeString(…)、DecodeInt(…)等 为了尽可能保持编码/解码的API干净,我想不出一种方法来对所有解码使用1种解码方法(目前最多使用2种公共方法) 请注意,我有一个方法可以获得解码字符

为了一个有趣的项目,我正在尝试实现BitTorrent规范,现在我正在处理其中的BEncoding部分

编码基本上可以从int/string/dictionary->string进行编码传输。我已经将所有不同的编码编写/测试/用作重载的Encode(…)方法,并将各个解码方法编写/测试/用作DecodeString(…)、DecodeInt(…)等

为了尽可能保持编码/解码的API干净,我想不出一种方法来对所有解码使用1种解码方法(目前最多使用2种公共方法)

请注意,我有一个方法可以获得解码字符串将具有的结果类型

客户机代码,现在每次他们想要解码消息时都必须看起来像这样:

string s = ...; // Encoded string
Type t = Encoder.GetDecodedType(s);
if (t == typeof(int))
    process(Encoder.DecodeInt(s));
else if (t == typeof(string))
    process(Encoder.DecodeString(s));
else if (t == typeof(Dictionary<string, string>))
    process(Encoder.DecodeStringDictionary(s));
else if (t == typeof(Dictionary<string, int>))
    process(Encoder.DecodeIntDictionary(s)):

其中,在这两种情况下,进程(…)很可能会在客户端重载函数,获取4种类型的解码值。

我认为您应该遵循Liskov替换原则,并为每种数据类型创建一个方法。这样,当您开始传递自定义对象时,您就不会不断地增加使用typeof的痛苦。再次阅读您的问题后,您已经知道传递给它的类型,因此进一步支持删除操作类型的需要

我认为您应该遵循Liskov替换原则,并为每个数据类型创建一个方法。这样,当您开始传递自定义对象时,您就不会不断地增加使用typeof的痛苦。再次阅读您的问题后,您已经知道传递给它的类型,因此进一步支持删除操作类型的需要

我感到困惑。为什么不在public Decode方法中简单地执行GetDecodedType逻辑并确定类型,然后在确定后进行不同的调用呢?

我很困惑。为什么不简单地在public Decode方法中执行GetDecodedType逻辑并确定类型,然后在确定后进行不同的调用?

您可以让DLR为您这样做

public static void Process(int i) { ... }
public static void Process(string s) { ... }
public static void Process(Dictionary<string, string> dic) { ... }
public static void Process(Dictionary<string, int> dic) { ... }

[...]

public dynamic Decode(string input)     // or 'object' if you prefer
{
    var t = GetDecodedType(input);
    if (t == typeof(int))
        return DecodeInt(input);
    else if (t == ...)
        // ...
}

[...]

string s = ...; // Encoded string
Process(Encoder.Decode(s));            // if you used 'dynamic' above
Process((dynamic)Encoder.Decode(s));   // if you used 'object' above
publicstaticvoidprocess(inti){…}
公共静态无效进程(字符串s){…}
公共静态无效进程(字典dic){…}
公共静态无效进程(字典dic){…}
[...]
公共动态解码(字符串输入)//或“对象”,如果您愿意
{
var t=GetDecodedType(输入);
if(t==typeof(int))
返回DecodeInt(输入);
else如果(t==…)
// ...
}
[...]
字符串s=…;//编码字符串
进程(编码器.解码);//如果您使用上面的“动态”
进程((动态)编码器.解码);//如果您使用上面的“对象”

您可以让DLR为您执行此操作

public static void Process(int i) { ... }
public static void Process(string s) { ... }
public static void Process(Dictionary<string, string> dic) { ... }
public static void Process(Dictionary<string, int> dic) { ... }

[...]

public dynamic Decode(string input)     // or 'object' if you prefer
{
    var t = GetDecodedType(input);
    if (t == typeof(int))
        return DecodeInt(input);
    else if (t == ...)
        // ...
}

[...]

string s = ...; // Encoded string
Process(Encoder.Decode(s));            // if you used 'dynamic' above
Process((dynamic)Encoder.Decode(s));   // if you used 'object' above
publicstaticvoidprocess(inti){…}
公共静态无效进程(字符串s){…}
公共静态无效进程(字典dic){…}
公共静态无效进程(字典dic){…}
[...]
公共动态解码(字符串输入)//或“对象”,如果您愿意
{
var t=GetDecodedType(输入);
if(t==typeof(int))
返回DecodeInt(输入);
else如果(t==…)
// ...
}
[...]
字符串s=…;//编码字符串
进程(编码器.解码);//如果您使用上面的“动态”
进程((动态)编码器.解码);//如果您使用上面的“对象”

如果您正在编写库/框架。。。这将是您努力工作中最宝贵的资源:-)我有硬拷贝,并从头到尾阅读:

从Microsoft

如果您正在编写库/框架。。。这将是您努力工作中最宝贵的资源:-)我有硬拷贝,并从头到尾阅读:

因为我不知道在设计时调用GetDecodedType的Decode方法的返回类型。这是通过WS?动态链接库?客户机如何执行这些方法?如果是通过WS,则必须定义返回类型,除非您要创建一个封装多个类型的自定义类型(以不同的方式冗余),否则似乎每个类型都有多个方法才是最好的选择…每一个类型都有多个方法,这是一个DLL,客户机代码大部分是我的,但最终(一旦有可用的东西)最终成为一个开源项目,所以我希望有一个尽可能干净的API。如果@Timwi发布的内容不起作用,那么我可能不得不使用我已经拥有的方法(多个方法)。因为我不知道在设计时调用GetDecodedType的解码方法的返回类型。这是通过WS?动态链接库?客户机如何执行这些方法?如果是通过WS,则必须定义返回类型,除非您要创建一个封装多个类型的自定义类型(以不同的方式冗余),否则似乎每个类型都有多个方法才是最好的选择…每一个类型都有多个方法,这是一个DLL,客户机代码大部分是我的,但最终(一旦有可用的东西)最终成为一个开源项目,所以我希望有一个尽可能干净的API。如果@Timwi发布的内容不起作用,那么我可能不得不使用我已经拥有的(多种方法)。哦。那看起来很性感。我会查一下,但是使用dynamic是否有框架版本依赖关系?@SnOrfus:恐怕它确实需要.NET 4.0或更高版本,是的。那很好,我最初是在3.5中工作的,但我并不局限于某个特定的版本。工作起来就像做梦一样。谢谢@TimwiOoh。那看起来很性感。我会查一下,但是使用dynamic是否有框架版本依赖关系?@SnOrfus:恐怕它确实需要.NET 4.0或更高版本,是的。那很好,我最初是在3.5中工作的,但我并不局限于某个特定的版本。工作起来就像做梦一样。谢谢@Timwi+1:这是一个我不知道的好资源。今晚我一定会吃的。谢谢乔尔。+1:这是我不知道的一个很好的资源。今晚我一定会吃的。谢谢你,乔尔。