IList<IClient> method<T>() ここで、 T :Iclient はクライアント オブジェクトをリストに追加できません
-
09-09-2019 - |
質問
public IList GetClientsByListofID(IList ids) ここで、 T :iclient {ilist clients = new list();client.Add( new Client(3));}
ここでコンパイラエラーが発生します。
「Bailey.Objects.Client」から「T」に変換できません
クライアント オブジェクトは IClient インターフェイスを実装します。ここでの私の目標は、クラス間の結合を緩めることです (DI の内容を学習すること)。あらゆる種類のクライアント オブジェクトを使用でき、それが返されると言えると考えていました。
ここで私は完全に基地外ですか?
ありがとう
ジョン・ホーキンス
解決
この方法で汎用制約を使用することはできません。コンパイラは、型パラメータが Client
単にそれが実装されているという理由だけで、 IClient
インターフェース?多くの型はそのインターフェイスを実装できないでしょうか?
この場合 (これは、インターフェイスではなく型を操作する必要がある場合です。) 次のように、型パラメータを型自体で制約する方が良いでしょう。
public IList<T> GetClientsByListofID<T>(IList<int> ids) where T : Client
{
IList<T> clients = new List<T>();
clients.Add(new Client(3));
// ...
}
それを実行すると、一般的なメソッドが必要かどうか疑問に思います。
public IList<Client> GetClientsByListofID(IList<int> ids)
{
IList<Client> clients = new List<Client>();
clients.Add(new Client(3));
// ...
}
他のヒント
Client
です IClient
.
T
です IClient
.
どこでそれを指定しましたか T
です Client
?どこにもない!
が必要だと思います IClientFactory
または IClientRepository
これにより、IClient インスタンスが作成/取得されます。これにより、このファクトリ/リポジトリのさまざまな実装を使用できるようになります。
これを試して:
public interface IClient
{
string Name { get; }
}
public class Client : IClient
{
public string Name { get; set; }
}
...
public IList<T> GetClientsByListofID<T>( IList<int> ids )
where T : class, IClient
{
var clients = new List<T>();
var client = new Client { Name = "bob" } as T;
clients.Add( client );
return clients;
}
使用法:
var clients = this.GetClientsByListOfID<Client>( null );
あなたの問題は制約の中にありません
where T : IClient
むしろリストを使用することです。
こんなことは言えません:
IList<T> clients = new List<T>();
clients.Add( new Client(3));
これを言うことができます:(これは、制約に「new」が含まれていることを前提としています)
IList<T> clients = new List<T>();
clients.Add( new T());
この場合、制約は次のようにする必要があります。
where T : new(), IClient
または、これを行うこともできますが、ジェネリックスはまったく使用されません。
IList<T> clients = new List<Client>();
clients.Add( new Client(3));
やろうとしていることができない理由は、コンパイラが型 T が Client 型であることを保証できないためです。そのため、コンパイラ エラーが発生します。それは実際にはあなたの制約とは何の関係もありません。
C# 3.0 ではジェネリックが共分散をサポートしていないため、あなたがやっていることは機能しません。
次のようなことができます:
interface IClient
{
int Id { get; set; }
}
class Client : IClient
{
public int Id { get; set; }
public Client() { }
}
// ...
public IList<T> GetClientsByListofID<T>(IList<int> ids) where T : IClient, new()
{
IList<T> clients = new List<T>();
clients.Add(new T() { Id = 3 });
// ...
return clients;
}
...しかし、ジェネリック医薬品が必要なのかどうかは疑問です。