User98743 Ответов: 1

Почему этот переключатель не возвращает значение?


Учитывая следующее:

ЗАПИСКА: Я указал Решение ниже, потому что оно исправило проблему в этом издевательском коде ниже, но для тех из вас, кто смотрит на это в будущем, мои свойства только для чтения являются допустимыми C#, введенными в C# 6.0.

using System;

public class RBOleDb
{
	public string DbType { get; }
	public string DbDataSource { get; }
	public string DbPath { get; }
	public string DbProvider { get; }


	/// <summary>
	/// Use this for connections to files, such as MS ACCESS, EXCEL, etc.
	/// </summary>
	/// <param name="file_path">Path to Database</param>
	public RBOleDb ( string file_path )
	{
		DbType = System.IO.Path.GetExtension ( file_path ).Replace ( "." , "" ).ToUpper ( );
		DbPath = file_path;
		DbDataSource = file_path;
	}


	public string GetProvider ( )
	{
		string result = "";
		switch ( DbType )
		{
			case "MDF":
				result = "SQLNCLI11";
				break;
			case "MDB":                   // return "Microsoft.Jet.OLEDB.4.0";
			case "ACCDB":
			case "XLSX":
			case "XLS":
			case "DBF":
				result = "Microsoft.ACE.OLEDB.12.0";
				break;
			default:
				result = "!!UNABLE TO DETERMINE PROVIDER!!";
				throw new ArgumentException ( $"DbType has a value of {DbType}, which is not valid.  RBDataOleDb clould not determine what database provider to use when connecting to database" );
		}
		return result;
	}
}

Почему GetProvider() не возвращает значение из оператора switch? Поскольку расширение входного файла-MDB, я ожидаю получить "Microsoft.ACE.OLEDB.12.0" обратно из этого метода.

Что я уже пробовал:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Ricks_Class_Testing
{
	class Program
	{
		static void Main ( string[ ] args )
		{
			string mdb = $@"D:\FIRECOMM\Ricks Dallas D Drive\db\COUNTY DATA\statecounty00.MDB";

			RBDataOleDb db = new RBDataOleDb ( mdb );
			Console.WriteLine ( db.DbType );
			Console.WriteLine ( db.DbPath );
			Console.WriteLine ( db.DbProvider );
		}
	}


}

1 Ответов

Рейтинг:
4

David_Wimbley

Так что первым делом, в RBOleDb класс, ваш DbType, DbDataSource, DbPath, and DbProvider у всех нет сеттера в свойстве, поэтому я не уверен, как ваш код даже компилируется, поэтому вам нужно будет изменить их с public string DbType { get; } к public string DbType { get; set; }.

Следующее, что я вижу, вы указываете, что проблемный класс-это RBOleDb но ваше использование в консольном приложении показывает, что вы используете другой класс под названием RBDataOleDb и я подозреваю, что это ваша проблема.

Я запустил ваш код, и он работает как есть, после того как я сделал ранее упомянутые исправления ошибок компиляции, поэтому я думаю, что вы перепутали, какой класс вы намеревались использовать в своем консольном приложении.

Такое использование

string mdb = @"D:\FIRECOMM\Ricks Dallas D Drive\db\COUNTY DATA\statecounty00.MDB";

            RBOleDb db = new RBOleDb(mdb);
            Console.WriteLine ( db.DbType );
            Console.WriteLine ( db.DbPath );
            Console.WriteLine ( db.DbProvider );

            Console.WriteLine("Result:" + db.GetProvider());


С помощью упомянутых исправлений в RBOleDb получим следующий результат

MDB
D:\FIRECOMM\Ricks Dallas D Drive\db\COUNTY DATA\statecounty00.MDB

Result:Microsoft.ACE.OLEDB.12.0


Animesh Datta

5!

[no name]

Спасибо Дэвиду и Анимешу. Геттеры не имеют сеттеров, потому что они доступны только для чтения и могут быть установлены только в конструкторе. Это действительно, хотя я, возможно, не использую его правильно. Я исправлю опечатку. Я высмеял это, чтобы быть кратким, но это не будет иметь ничего общего с переключателем. Когда я заменил переключатель на операторы IF THEN, он работал нормально... интересно, почему.

David_Wimbley

Просто заметка о сеттерах, не говоря уже о самом сеттере, не позволяет ему просто иметь его волшебным образом. Если вы хотите, чтобы он работал только в конструкторе, то вам нужно прикрепить readonly модификатор. Будет выглядеть примерно так private readonly string DbType {get; private set;} но в этой ситуации вся ваша собственность должна быть частной, так как она не может быть оформлена только для чтения, а также публичной.

Это, или если вы хотите, чтобы только сам класс устанавливал значение и ничего за его пределами, вы можете сделать сеттер private Так что это будет выглядеть примерно так public string DbType { get; private set; }

Исправление предоставленного вами класса (в нем были все ошибки компиляции, о которых я упоминал) и настройка вашего примера использования для использования RBOleDb вместо RBDataOleDb оператор switch работал нормально.

Если оператор switch не работает, это звучит так, как будто у вас есть что-то еще, и вам нужно добавить точки останова в свой код и начать пошагово отлаживать то, что происходит.

Richard Deeming

Нет - автоматические свойства только для чтения без сеттеров действительны в C# уже довольно давно.

C# : новый и улучшенный C# 6.0[^] - прокрутите вниз до пункта "инициализаторы авто-свойств".

David_Wimbley

Я знал об этом. public string DbType { get; } = "MDB"; но ты говоришь делать public string DbType { get; }...затем позже в коде DbType = "MDF"; теперь это действительно так? Я не вижу этого в статье, честный вопрос.

Richard Deeming

Только если назначение происходит в конструкторе. Это то же самое, что добавить readonly на заднее поле.

Alex Schunk

Я взглянул на сгенерированный Ил... Похоже, что резервное поле свойства сделано только для чтения, и значение присваивается непосредственно резервному полю.
Приятно это знать.

Richard Deeming

Кроме того, вы не можете добавить readonly модификатор свойства В C# - это VB.NET синтаксис. :)

David_Wimbley

Хороший улов, вот что я получаю за то, что печатаю его с макушки головы.

BillWoodruff

+5

[no name]

Спасибо, @BillWoodruff

@David_Wimbley, я собираюсь принять ваше решение, потому что оно действительно исправило проблему с фиктивным кодом. В конце концов, я просто снял выключатель и заменил его чем-то другим, потому что у меня не было времени. Спасибо за вашу помощь!