C# 在 if 语句中声明变量,Common Base Class

C# Declare Variable in if statement, Common Base Class

我正在尝试将字符串传递到方法中,并根据传入的字符串实例化 BasicHttpBinding 或 WSHttpBinding。以下 if 语句在我的代码中。

if(bindingObject == "basic")
{System.ServiceModel.BasicHttpBinding binding = new System.ServiceModel.BasicHttpBinding();}
else
{System.ServiceModel.WSHttpBinding binding = new System.ServiceModel.WSHttpBinding();

这段代码给出了错误

The name 'binding' does not exist in the current context

根据我的研究,如果我想使用名为 binding 的变量,无论哪个服务模型,我似乎都必须在两个服务模型之间使用一个公共基础 class我需要用。

我的问题是,什么是可行的共同基础 class?或者有没有办法做到这一点。我找到的最接近的是 System.ServiceModel.Channels.Binding 但后来我得到了诸如

之类的错误

does not contain a definition for 'MaxBufferPoolSize' and no extension method 'MaxBufferPoolSize' accepting a first argument of tyep 'System.ServiceModel.Channels.Binding' could be found

首先:BasicHttpBindingBasicHttpBinding 都需要从相同的基础派生 class 或实现相同的 interface

如果您正在使用 visual studio,您可以将光标放在类型上并按 f12 以查看它们派生自哪些类型以及它们实现了哪些接口。适合使用的类型取决于您要对它们执行的操作。

根据 BasicHttpBinding and WSHttpBinding 的文档,共同基础 class 似乎是 System.ServiceModel.Channels.Binding

无论如何你应该使用f12来检查,因为那里可能有一个接口定义了你需要使用的成员。

其次,您必须在 if 语句的上下文之外声明它

System.ServiceModel.Channels.Binding binding;
if(bindingObject == "basic")
{
    binding = ...
}
else
{
    binding = ...
}

您可以使用绑定基础 class 或 IBindingRuntimePreferences 接口,如果它提供对您需要的功能的访问。

   //System.ServiceModel.Channels.Binding binding;
    System.ServiceModel.Channels.IBindingRuntimePreferences binding;
    if(bindingObject == "basic")
       binding = new System.ServiceModel.BasicHttpBinding();}
    else
       binding = new System.ServiceModel.WSHttpBinding();

这是动态关键字的完美用例

        dynamic binding;
        if (bindingObject == "basic")
        {
            binding = new System.ServiceModel.BasicHttpBinding();
        }
        else
        {
            binding = new System.ServiceModel.WSHttpBinding();
        }

那么您可以访问以下内容

        binding.MaxBufferPoolSize = 10;

您遇到的问题是因为局部变量的作用域。根据 MSDN 范围界定的 C# 规范,

Scopes can be nested, and an inner scope may redeclare the meaning of a name from an outer scope (this does not, however, remove the restriction imposed by §1.20 that within a nested block it is not possible to declare a local variable with the same name as a local variable in an enclosing block).

另一个标识符范围规范,

For each occurrence of a given identifier as a simple-name in an expression or declarator, within the local variable declaration space, immediately enclosing block, or switch-block of that occurrence, every other occurrence of the same identifier as a simple-name in an expression or declarator within the immediately enclosing block or switch-block must refer to the same entity. This rule ensures that the meaning of a name is always the same within a given block, switch block, for-, foreach- or using-statement, or anonymous function.

现在转到您遇到的错误: BasicHttpBinding 派生自 HttpBindingBase,后者派生自 Binding 并实现 IBindingRuntimePreferencesWSHttpBinding 派生自 WSHttpBindingBase 派生自 Binding 并实现 IBindingRuntimePreferences.

但是 属性 MaxBufferPoolSize 驻留在 HttpBindingBase 和 WsHttpBindingBase 中,而不是在它们共同的父 BindingIBindingRuntimePreferences 中。这意味着您不能使用通用的 class 来表示这些绑定。相反,您应该使用 dynamic 作为类型,它会在运行时而不是编译时绑定类型。

Public dynamic GetBinding(string bindingObject)
 {
    if (bindingObject == "basic")
    {
        binding = new System.ServiceModel.BasicHttpBinding();
    }
    else
    {
        binding = new System.ServiceModel.WSHttpBinding();
    }

   return binding;
  }