TheBigBearNow Ответов: 1

Смущение по поводу ошибки приведения работало и раньше..


Всем привет,
Я не знаю, почему я получаю ошибку в актерском составе. Я могу войти в систему как администратор без проблем. Я использую наследование с классом customer, наследующим свойства от пользователя. Администратор-это просто обычный пользователь. Клиент имеет только несколько дополнительных свойств, но раньше немного раньше я мог запустить свою программу без ошибок, а теперь вдруг получаю эту ошибку. Я так запутался, что он вышел ниоткуда, я подумал, что, может быть, это ошибка компилятора, поэтому я очистил/перестроил и все еще ошибка.....
//LOGIN SCREEN AND WHERE THE ERROR OCCURS IN MY CATCH CLAUSE *** 			private void BtnLoginUser_Click(object sender, RoutedEventArgs e)    {
                try     {
                    loginUser = SQLuserAccess.UserLogin(txtUsername.Text, txtPassword.Password.ToString());
                    if (txtUsername.Text == loginUser.Username && txtPassword.Password == loginUser.Password)   {
                        if (loginUser.IsAdmin == true){
                            Window showAdminSrc = new AdminWindow(loginUser);
                            showAdminSrc.Show();
                            Close();
                        }else if (loginUser.IsAdmin == false)   {
                            Customer CastUser = new Customer();
                                CastUser = (Customer)loginUser;
          Window nonAdmin = new CustomerScreen(CastUser);//((Customer)loginUser);
                            nonAdmin.Show();
                            Close();
                        }  else
                            lblInvalidText.Content = "Admin is not True or False!";
                    }
                    else  {
                        lblInvalidText.Visibility = Visibility.Visible;
                    }
                } catch(Exception ex)     {
                    ex.Message.ToString();
                    throw ex;
                }
            }
        }	//CUSTOMER SCREEN LOADING CONSTRUCTOR NOTHING SPECIAL..       		 public CustomerScreen(User user) {
            customerUser = (Customer)user;
            InitializeComponent();
            //Display Users 'username' on Src / *future - Data Binding.
            TxtBlockName.Text = "Hello:" + Environment.NewLine + customerUser.Username;
        }


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

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

1 Ответов

Рейтинг:
9

OriginalGriff

Мы не видим определений этого понятия. loginUser и user которые являются единственными явными приведениями в этом коде; мы также не можем видеть, какой тип SQLuserAccess.UserLogin возвращается, или что там внутри user до того, как ты это бросишь.

Поэтому Запустите свой код в отладчике и посмотрите, что именно содержат переменные.

На первый взгляд вы говорите, что Customer является производным от User, но я бы заподозрил, что UserLogin возвращает член базового класса User, а не клиент - и вы ничего не можете "перевернуть".

public class User {}
public class Customer : User {}
...
Customer c;
User u = new Customer ();  // Fine, Customer derived from User.
c = (Customer) u;          // Also fine, u contains a Customer.
u = new User();
c = (Customer) u;          // Error because you can't upcast the User.


TheBigBearNow

Вот Логическое_имя_пользователя
Класс User - это просто класс со свойством Username password id, а клиент просто добавляет несколько свойств, таких как firstname и т. д..

Я думаю, что понимаю, к чему вы клоните, потому что да, логин действительно возвращает пользователя, а не клиента, я постараюсь понять это иначе.
В отладчике он получает правильного пользователя, и я помещаю этого пользователя на следующий экран и бросаю его в клиента.я беру объект пользователя в CustomerScreen, а в конструкторе я бросаю этот конкретный объект пользователя клиенту.
[код]
публичный статический пользователь UserLogin(строковое имя пользователя, строковый пароль)
{
//SQL Login Query.
строка SQLloginQuery = "SELECT * FROM Users WHERE Username=@username AND Password=@password";
SqlCommand cmdLogin = новая команда SqlCommand(SQLloginQuery, соединение);
cmdLogin.Параметры.AddWithValue("@username", имя пользователя);
cmdLogin.Параметры.AddWithValue("@password", пароль);
пробовать
{
соединение.Открыть();
//int result = (int)cmdLogin.Executescalar так();
SqlDataReader reader = cmdLogin.ExecuteReader(CommandBehavior.SingleRow);
если (читатель.читать())
{
Пользователь user = новый пользователь
{
UserID = Конвертировать.ToInt32(reader["UserId"]),
Username = reader["имя пользователя"].Метод toString(),
Password = reader["пароль"].Метод toString(),
IsAdmin = Преобразовать.ToBoolean(читатель["IsAdmin"]),
UserCreatedDate = Конвертировать.ToDateTime(reader["UserCreatedDate"])
};
возврат пользователя;
}
еще
возвращать null;
}
[/код]

TheBigBearNow

Что мне делать, чтобы поднять настроение
[код]c = (клиент) u;[/код]

потому что да, именно в этом и заключается проблема.
Он у тебя точно включен.

OriginalGriff

Вы вообще не можете поднять настроение! Подумайте об этом - если бы вы могли это сделать:

public class A {}
public class B : A {public string s;}
...
A a = new A();
B b = (B) a;
Console.WriteLine(b.s);

Откуда берется строка "s"? Что в нем содержится? Система не может волшебным образом создать его, и экземпляр A в переменной не имеет никакого пространства, выделенного для строки - поэтому, когда вы попытаетесь напечатать его значение, вы получите доступ к памяти, которая не выделена для экземпляра, - и это может привести к сбою вашего кода очень интересным образом!

TheBigBearNow

Хорошо, что бы я сделал, чтобы исправить эту ошибку?
В userlogin создайте еще один loginmethod для клиента и сохраните Мой для пользователя или просто верните клиента в loginmethod вместо пользователя, потому что мой клиент унаследует все свойства пользователя, а также будет иметь свои собственные свойства клиента.
Я попробовал такой код, но потом получил ошибку nullreference, как вы и сказали, потому что здесь нет выделенной памяти.
[код]
CastUser клиент = loginUser по мере того как клиент;
Window nonAdmin = новый CustomerScreen(CastUser);
[/код]

OriginalGriff

Самым простым решением, вероятно, является создание конструктора Customer, который принимает пользователя и создает на его основе новый экземпляр.
Но это неуклюже (и может вызвать проблемы в другом месте, если вы делаете ссылочные сравнения) - я думаю, что вам было бы лучше внимательно взглянуть на вашу иерархию классов и на то, как вы ее используете: я бы сразу сказал, что весь ваш дизайн несовершенен, и вы замазываете фундаментальные ошибки!

OriginalGriff

И "как" ничего не решит: оно не творит волшебства!

Customer CastUser = loginUser as Customer;
это короткая форма для этого:
Customer CastUser = null;
if (loginUser is Customer) CastUser = (Customer) loginUser;

TheBigBearNow

спасибо
Теперь он у меня немного работает. просто забрал клиента с логином, переключился обратно на пользователя и собираюсь заглянуть в него, чтобы я мог использовать свои свойства клиента на своих последующих экранах. Я все еще учусь. Не могли бы вы быстро взглянуть на эти классы-вот как я должен это сделать?
еще раз спасибо. П. С. Как я [код][/код] в этих комментариях?

[код]
//Мой пользовательский класс
пользователь открытого класса
{
//РЕАЛИЗАЦИЯ/ОБНОВЛЕНИЕ КОДА C# ДО ВЕРСИИ 7.0.
//создать свойство UserID
частный int _userId;
общественного int идентификатор пользователя
{
вам =&ГТ; _userId; //get { возвращение _userId; }
комплект =&ГТ; _userId = значение; //множества { _userId = значение; }
}
//создать свойство username
частная строка _username;
общественного строка имя пользователя
{
get => _username; //get { return username; }
комплект =&ГТ; _username = значение; //множества { _username = значение; }
}
//создать свойство пароля
частная строка _password;
публичный строковый пароль
{
вам =&ГТ; _password; //get { возвращение _password; }
комплект =&ГТ; _password = значение; //множества { _password = значение; }
}
//создать свойство isAdmin
частный bool _isAdmin;
public bool IsAdmin
{
вам =&ГТ; _isAdmin; //get { возвращение _isAdmin; }
комплект =&ГТ; _isAdmin = значение; //множества { _isAdmin = значение; }
}
//Создание нового свойства подумайте об этом при создании базы данных.
//создать свойство UserCreatedDate
частная Датавремя _userCreatedDate;
общественная datetime UserCreatedDate
{
вам =&ГТ; _userCreatedDate; //get { возвращение _userCreatedDate; }
комплект =&ГТ; _userCreatedDate = значение; //множества { _userCreatedDate = значение; }
}

//Конструктор по умолчанию для пользовательского класса
публичный пользователь() { }

//Конструктор без идентификатора пользователя (используется для создания нового пользователя)
публичный пользователь(string uname, string pass, bool isadmin, DateTime userDate)
{
Имя пользователя = uname;
Пароль = пропуск;
IsAdmin = isadmin;
UserCreatedDate = userDate;
}
//Конструктор с идентификатором пользователя (используется для обновления текущего выбранного пользователя)
пользователей общедоступных(int идентификатор, строка команде uname, строки проходят, типа bool isadmin, Датавремя userDate)
{
Идентификатор = идентификатор;
Имя пользователя = uname;
Пароль = пропуск;
IsAdmin = isadmin;
UserCreatedDate = userDate;
}
//Конструктор для обновления и сохранения исходной даты создания ~~(обновление: не думаю, что мне это нужно)~~11/2/18~
публичный пользователь(string uname, string pass, bool isadmin)
{
Имя пользователя = uname;
Пароль = пропуск;
IsAdmin = isadmin;
}
//МОЙ КЛАСС КЛИЕНТОВ
публичный класс клиент : пользователь
{
//Свойства для вновь созданного класса Customer. В 7.0
//Кодклиента свойства внешнего ключа в идентификатор пользователя.
//private int _customerId;
//общественных инт "Кодклиента"
//{
// вам =&ГТ; _customerId;
// set => _customerId = значение;
//}
////Свойство First name.
//частная строка _firstname;
//public string FirstName
//{
// вам =&ГТ; _firstname;
// set => _firstname = значение;
//}

// ~ ПЕРЕКЛЮЧЕНИЕ НА ИСПОЛЬЗОВАНИЕ АВТОМАТИЧЕСКИ РЕАЛИЗОВАННЫХ СВОЙСТВ ~
//Кодклиента собственность наследует внешний ключ на идентификатор пользователя.
public int CustomerId { get; set; }

/Свойство /FirstName.
общественного строка имя { получить; набор; }

/Свойство /LastName.
общественного строка имя { получить; набор; }

//свойство address.
общественного строка адреса { получить; набор; }

//городское имущество.
public string City { get; set; }

//государственное имущество.
общественного строка состояния { получить; набор; }

//Почтовый Индекс Недвижимости.
публ