私はC#を初めて使用します。 PersonsクラスとPersonsクラスを継承するUserクラスがあります。私のコンソールは、配列にユーザーを入力します。次に、users idを入力するだけで、users配列にあるユーザーにメモを追加できます。私のPersonsクラスには、このユーザーがusers配列にあるかどうかを検索する必要があるこの関数があります。
public static Persons FindPerson(Persons[] persons, int noteid)
{
foreach (Persons person in persons)
if (person.ID == noteid) return person;
return null;
}
私のUserクラスには、users配列にあるIDを取得するまで、IDの入力全体をループする関数があります。
public static User SelectUser(User[] users)
{
while (true)
{
Console.Write("Please enter the User id: ");
string input = Console.ReadLine();
int id;
if (int.TryParse(input, out id))
{
Persons person = Persons.FindPerson(users, id);
if (person != null) return person; // fail on "return person"
}
Console.WriteLine("The User does not exist. Please try again.");
}
}
Ifステートメントの「returnperson」にこのエラーメッセージが表示されることを除いて、すべて正常に機能します。
タイプ「UserCustomerNotes.Persons」を「UserCustomerNotes.User」に暗黙的に変換することはできません。明示的な変換が存在します(キャストがありませんか?)
誰か助けてもらえますか?前もって感謝します。
Person
は必ずしもUser
ではないため、コンパイラーはPerson
をUser
に暗黙的に変換することはできません。あなたの特定のケースでは、あなたはknowUser
sのリストを持っているので、「このPerson
は実際にはUser
"次のように:
if (person != null)
return (User) person;
キャスト ((User)
)インスタンスが実際にはUser
でない場合、実行時に例外がスローされますが、最初はUser
sのコレクションから始めたので、心配する必要はありません。 。
User
はPerson
を継承するため、ランダムなPerson
をUser
に暗黙的に変換することはできません(ただし、User
を暗黙的に変換することはできます) Person
)。
_User[]
_をFindPerson(users, id)
に渡すので、返された人が実際にUser
であると確信できるので、次のようにキャストできます。
_return (User)person;
_
編集:キャストを完全に回避するために、FindPerson
でジェネリックを使用することを検討してください。
_public static T FindPerson<T>(IEnumerable<T> persons, int noteid)
where T : Person
{
foreach (T person in persons)
{
if (person.ID == noteid)
{
return person;
}
}
return null;
}
public static User SelectUser(User[] users)
{
while (true)
{
Console.Write("Please enter the User id: ");
string input = Console.ReadLine();
int id;
if (int.TryParse(input, out id))
{
User person = Persons.FindPerson(users, id);
if (person != null)
{
return person;
}
}
Console.WriteLine("The User does not exist. Please try again.");
}
}
_
リターンスニペットを次のように書き直す必要があります。
User user = Persons.FindPerson(users, id) as User;
if (user != null) return user;
あなたが抱えていた問題は、より派生したクラスを返すはずのメソッドから基本クラスを返そうとしたことでした。コンパイラは自動的にダウンキャストすることはできませんが(Persons
-> User
)、アップキャストすることはできます(User
-> Persons
)
明示的または暗黙的な演算子を実装する必要があります。
class ClassA
{
public string Property1 { get; set; }
public static explicit operator ClassB(ClassA classA)
{
return new ClassB() { Property2 = classA.Property1 };
}
}
class ClassB
{
public string Property2 { get; set; }
}
var a = new ClassA() {Property1 = "test"};
ClassB b = (ClassB)a;
Console.WriteLine(b.Property2); // output is "test"
とにかく、最初のメソッドにはLINQ拡張メソッドを使用することをお勧めします。
using System.Collections.Generic;
using System.Linq;
public static Persons FindPerson(IEnumerable<Person> persons, int id)
{
return persons.FirstOrDefault(p => p.ID == id);
}
ずっと良く見えますよね?