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();