Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.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语言中设计可接受多种选择的API?_C# - Fatal编程技术网

C# 在C语言中设计可接受多种选择的API?

C# 在C语言中设计可接受多种选择的API?,c#,C#,我有一个接口/抽象类,其中的实现可以支持任意大小的名称、标识符字典。每个实现将有一个不同的标识符格式,该标识符是特定于实现的 调用方需要从提供者检索名称列表,并使用这些名称询问用户他关心的内容。用户可以选择一个或多个 我考虑了下面的设计,其中调用者获取一个名称数组,并通过传入一个int数组来设置用户的选择,标识用户选择的名称的数组标记 public abstract String[] GetNames(); public abstract void SetNamesToUse(int[] nam

我有一个接口/抽象类,其中的实现可以支持任意大小的名称、标识符字典。每个实现将有一个不同的标识符格式,该标识符是特定于实现的

调用方需要从提供者检索名称列表,并使用这些名称询问用户他关心的内容。用户可以选择一个或多个

我考虑了下面的设计,其中调用者获取一个名称数组,并通过传入一个int数组来设置用户的选择,标识用户选择的名称的数组标记

public abstract String[] GetNames();
public abstract void SetNamesToUse(int[] names);
对此不满意,我还考虑了一个模型,其中将传递一个对象列表:

public class NameObject {
    public bool SelectedByUser;
    public String Name;
    private String ProviderSpecificData;
}

...

public abstract List<NameObject> GetNames();
public abstract void SetNamesToUse(List<NameObject> names);
这对打电话的人来说似乎更干净、更容易

我还有什么选择?你是如何解决类似问题的?

这个呢

interface IIdentifier
{
    string Name {get;}
}

abstract class Identifier<T> : IIdentifier
{
    private readonly string _name;
    private readonly T _id;
    public string Name {get;set;}

    protected Identifier(string name, T id)
    {
        _id = id;
        _name = name;
    }
}

class GuidIdentifier : Identifier<Guid>
{
    public GuidIdentifier(string name, Guid identifier)
        :base(name, identifier)
    {
        //?
    }
}

class UserOptions
{
    private IEnumerable<IIdentifier> _identifiers;

    public IEnumerable<IIdentifier> Identifiers {get {return _identifiers;}}

    public IIdentifier Selected {get;set;}

    public UserOptions(IEnumerable<IIdentifier> identifiers)
    {
        _identifiers = identifiers;
    }
}   
这个怎么样

interface IIdentifier
{
    string Name {get;}
}

abstract class Identifier<T> : IIdentifier
{
    private readonly string _name;
    private readonly T _id;
    public string Name {get;set;}

    protected Identifier(string name, T id)
    {
        _id = id;
        _name = name;
    }
}

class GuidIdentifier : Identifier<Guid>
{
    public GuidIdentifier(string name, Guid identifier)
        :base(name, identifier)
    {
        //?
    }
}

class UserOptions
{
    private IEnumerable<IIdentifier> _identifiers;

    public IEnumerable<IIdentifier> Identifiers {get {return _identifiers;}}

    public IIdentifier Selected {get;set;}

    public UserOptions(IEnumerable<IIdentifier> identifiers)
    {
        _identifiers = identifiers;
    }
}   

我喜欢你第二个例子的连贯性。它与NameObject类或List的使用无关。您也可以使您的第一个示例保持一致:

public abstract String[] GetNames();
public abstract void SetNamesToUse(String[] names);
要选择全部,现在只需编写

SetNamesToUse(GetNames());
根据我的经验,一个用例不足以从许多可能的设计选项中进行选择。然而,如果你为更多的用例编写客户机代码,事情就开始向你袭来

在上面的一行示例中,GetNames调用看起来很模糊。这是一个从用户那里获取名称的调用还是一个获取所有可用名称的调用?方法名称更改可以澄清这一点:

SetNamesToUse(GetAllNames());
费伦茨·米哈利
我喜欢你第二个例子的一致性。它与NameObject类或List的使用无关。您也可以使您的第一个示例保持一致:

public abstract String[] GetNames();
public abstract void SetNamesToUse(String[] names);
要选择全部,现在只需编写

SetNamesToUse(GetNames());
根据我的经验,一个用例不足以从许多可能的设计选项中进行选择。然而,如果你为更多的用例编写客户机代码,事情就开始向你袭来

在上面的一行示例中,GetNames调用看起来很模糊。这是一个从用户那里获取名称的调用还是一个获取所有可用名称的调用?方法名称更改可以澄清这一点:

SetNamesToUse(GetAllNames());
费伦茨·米哈利

@IanMercer我的想法是提供商无论如何都需要保存此列表,我还可以将选择器包含在其中。你建议使用HastSet是一个很好的建议;我会考虑的。谢谢。@IanMercer我的想法是提供者无论如何都需要保存这个列表,我也可以在其中包含选择器。你建议使用HastSet是一个很好的建议;我会考虑的。谢谢