C# объявить переменную в операторе if, общий базовый класс

Я пытаюсь передать строку в метод и в зависимости от того, какая строка передана, создать экземпляр BasicHttpBinding или WSHttpBinding. Следующая инструкция if есть в моем коде.

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

Этот код дает мне ошибку

Имя "связывание" не существует в текущем контексте

Судя по моим исследованиям, мне кажется, что я должен использовать общий базовый класс между двумя сервисными моделями, если я хочу использовать переменную с именем binding, независимо от того, какую ServiceModel мне нужно использовать.

У меня вопрос, какой общий базовый класс будет работать? Или есть способ сделать это. Самый близкий я нашел System.ServiceModel.Channels.Binding, но затем я получаю ошибку, такую ​​как

не содержит определения для MaxBufferPoolSize и не найден метод расширения "MaxBufferPoolSize", принимающий первый аргумент типа "System.ServiceModel.Channels.Binding"

4 ответа

Решение

Проблема, с которой вы сталкиваетесь, связана с областью видимости локальных переменных. Согласно спецификации C# для определения области из MSDN,

Области действия могут быть вложенными, а внутренняя область действия может переопределить значение имени из внешней области действия (однако это не снимает ограничение, наложенное §1.20, что в рамках вложенного блока невозможно объявить локальную переменную с то же имя, что и локальная переменная во включающем блоке).

Другой из спецификации для идентификаторов области видимости,

Для каждого вхождения данного идентификатора в качестве простого имени в выражении или в объявителе, в пространстве объявления локальной переменной, непосредственно вмещающем блоке или блоке-переключателе этого вхождения, в каждом другом вхождении того же идентификатора, что и в простом имени в выражение или декларатор в непосредственно включающем блоке или блоке переключателя должны ссылаться на одну и ту же сущность. Это правило гарантирует, что значение имени всегда будет одинаковым внутри данного блока, блока переключателей, оператора for, foreach- или using-оператора или анонимной функции.

Теперь перейдем к ошибке, с которой вы столкнулись:BasicHttpBinding является производным от HttpBindingBase, который получен из Binding и реализовать IBindingRuntimePreferences,WSHttpBinding получен из WSHttpBindingBase, который получен из Binding и реализовать IBindingRuntimePreferences,

Но собственность MaxBufferPoolSize находится в HttpBindingBase и WsHttpBindingBase, а не в их общем родителе Binding или же IBindingRuntimePreferences, Это означает, что вы не можете использовать общий класс для представления этих привязок. Скорее вы должны использовать dynamic как тип, который связывает типы во время выполнения, а не во время компиляции.

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

   return binding;
  }

Первый: оба BasicHttpBinding а также BasicHttpBinding нужно либо наследовать от того же базового класса, либо реализовать тот же интерфейс

Если вы используете Visual Studio, вы можете навести курсор на типы и нажать f12 чтобы увидеть, какие типы они производные и какие интерфейсы они реализуют. Тип, который подходит для использования, зависит от того, что вы хотите с ними делать.

Согласно документации для BasicHttpBinding и WSHttpBinding, общий базовый класс выглядит следующим образом: System.ServiceModel.Channels.Binding,

Вы должны использовать f12 проверить в любом случае, потому что там, вероятно, есть интерфейс, который определяет членов, которые вам нужно использовать.

Во-вторых, вы должны объявить это вне контекста вашего заявления if

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

Это идеальный вариант использования для динамического ключевого слова

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

Тогда вы можете получить доступ к следующим

        binding.MaxBufferPoolSize = 10;

Вы можете использовать базовый класс Binding или интерфейс 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();
Другие вопросы по тегам