Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.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#最佳实践:编写一个方法,返回属于类本身的方法参数deptency中的值_C# - Fatal编程技术网

C#最佳实践:编写一个方法,返回属于类本身的方法参数deptency中的值

C#最佳实践:编写一个方法,返回属于类本身的方法参数deptency中的值,c#,C#,首先,我很抱歉我的标题太差了!如果您有更好的标题,只需更改或发表评论=) 我有这门课: public class Config { public Provider1 Provider1 { get; set; } public Provider2 Provider2 { get; set; } public Provider3 Provider3 { get; set; } public Provider4 Provider4 { get; set; }

首先,我很抱歉我的标题太差了!如果您有更好的标题,只需更改或发表评论=)

我有这门课:

public class Config
{
    public Provider1 Provider1 { get; set; }
    public Provider2 Provider2 { get; set; }
    public Provider3 Provider3 { get; set; }
    public Provider4 Provider4  { get; set; }
    public Provider5 Provider5 { get; set; }

    public int GetNumber(string provider)
    {
        ...
    }
}
每个提供程序都有一个数字属性:

public interface IProvider
{
    int Number{ get; set; }
}
在提供者的依赖关系中,我想返回提供者的编号

IDictionary<string, IProvider> providers = new Dictionary<string, IProvider>();
你会怎么做


我不想使用大的开关块

提供程序的编号是所有提供程序实现的基类或接口的属性,还是其在配置类中位置的属性

编辑

如果它是提供者的属性,那么访问它的正确方法是通过提供者。换句话说,
Config
应该返回
IProvider
(或您所称的任何内容)的某个子项,然后调用方可以链接到其
Number
属性

编辑

部分问题是您列举了属性名称(“prop1”、“prop2”等)。为什么不用索引器或获取索引的方法替换它呢

另一个问题是,您似乎希望按提供者名称查找
编号
,但没有显示名称所在的位置。你是说类名吗?

创建一个接口

IGiveANumberbackable { GetNumber(); }

在类中实现这一点

在类上调用此方法,而不是GetNumber()

公共接口IProvider
{
整数{get;set;}
}
公共类配置
{
public int GetNumber(),其中T:IProvider
{
//代码以查找所需的提供程序
IProvider foundProvider=ProviderFactoryMethodHere(类型为(T));
返回foundProvider.Number;
}
}
现在,您的所有提供程序类都需要实现IProvider接口,并且您需要实现一个工厂,该工厂将根据您在泛型方法中请求的类型向您返回正确的提供程序

// Test code example
Config configImpl = new Config();
int numberOfProvider = configImpl.GetNumber<Provider1>();
Assert.Equal(1, numberOfProvider);
//测试代码示例
Config configImpl=new Config();
int numberOfProvider=configImpl.GetNumber();
Assert.Equal(1,numberOfProvider);
我将添加一个简单的ProviderFactoryMethod示例。请注意,我们也可以将此方法设置为泛型,而不是将类型作为参数传递,但我将保持示例不变

public IProvider ProviderFactoryMethodHere(Type providerRequested)
{
    Dictionary <Type, IProvider> providerDict;
    if (providerDict == null)
    {
      // populate dictionary with providers, keyed by their type
      providerDict = new Dictionary<Type, IProvider>();
      providerDict.Add(typeof(Provider1), new Provider1());

      // repeat for all providers, this is pretty simple but definitely works
      // we could use other ways of holding on to your provider instances
    }
    if (providerDict.HasKey(providerRequested))
    {
        return providerDict[providerRequested];
    }
    // could throw exception here if you want to use that kind of error
    // handling, but we'll just return null for now
    return null;
}
public IProvider ProviderFactoryMethodHere(输入providerRequested)
{
词典提供者词典;
if(providerDict==null)
{
//使用提供程序填充字典,并按其类型键入
providerDict=新字典();
Add(typeof(Provider1),newprovider1());
//对所有提供者重复,这非常简单,但绝对有效
//我们可以使用其他方法保留您的提供者实例
}
if(providerDict.HasKey(providerRequested))
{
返回providerDict[providerRequested];
}
//如果要使用此类错误,可以在此处引发异常
//处理,但我们现在只返回null
返回null;
}

干杯。

理想情况下,您希望所有提供程序都从一个基类(或接口)继承,该基类(或接口)提供每个提供程序的数量

abstract class Provider {
   public int Number { get; set; }
}

class Provider1 : Provider { ... }
然后,您可以将所有提供程序转储到哈希表中,该哈希表由您正在使用的字符串进行键控。例如:

public class Config
{
   Dictionary<string, Provider> _providers = new Dictionary<string, Provider>();

   // .. all of your providers ..

   public int GetNumber(string provider)
   {
      if (!_providers.HasKey(provider))
         throw ArgumentException();
      return _providers[provider].Number;
   }
}
公共类配置
{
字典_providers=新字典();
//…您的所有供应商。。
public int GetNumber(字符串提供程序)
{
if(!\u providers.HasKey(provider))
抛出ArgumentException();
返回_providers[provider]。编号;
}
}

将它们添加到字典中,该字典由识别提供者的字符串键入

IDictionary<string, IProvider> providers = new Dictionary<string, IProvider>();
IDictionary providers=new Dictionary();
然后,通过检查字典是否包含传递到GetNumber方法的值,可以从字典中获取值。如果它在那里,您可以从字典中取出它并调用提供者的Number属性

IDictionary<string, IProvider> providers = new Dictionary<string, IProvider>();
返回提供程序[提供程序]。编号


请注意,在定义字典时,IProvider需要是所有提供程序从中继承的基类。

继承接口的是提供程序的属性。这不是答案,请对他的问题进行注释。@Blub:更好,我来回答。有趣的是,我独立地选择了相同的属性和接口名称。@Rookian:好的,但它们的数量是任意的。所以,与其让每个人都有自己的财产,不如让他们共享一个索引器。呃,工厂是什么样子的?顺便说一句,GetNumber不能是泛型。。。提供程序必须作为字符串参数传递。看起来您只是在将switch语句下推到工厂中。@Rookian-我故意删除了“string”映射值,因为它不是需求中描述的必需值。对于不熟悉泛型并直接使用类型“查找”所需内容的人来说,这是非常常见的。问题代码的更详细用法将演示我们是否真正需要字符串。你能告诉我字符串是什么样子,并描述为什么需要字符串吗?@RexM-我们不需要switch语句。我现在演示了一个字典。在UI中,我只有字符串作为常量值。我知道用Name属性扩展IProvider接口。当我加载配置文件时,我将所有提供程序放在一个列表中。然后我实现了GetProviderByName和GetNumberSo方法,而不是调用
IProvider.GetNumber
,您想调用
IGiveANumberbackable.GetNumber
?或者我遗漏了什么?抛开使用公共基而不是公共接口,为什么我们要对
Number
属性进行特殊处理,而不是仅仅根据其名称返回任何提供者?因为OP要求这样做?