正在转换对象或对象<;T>;到对象<;T、 T>;
本文关键字:对象 gt lt 转换 | 更新日期: 2023-09-27 18:29:34
我一直在关注Imar Spaanjars关于ASP.NET N层应用程序的博客,并了解ASP.NET Identity的代码实践。
我在继承和调用基方法方面遇到了一些麻烦。
信息
首先让我向您展示基本代码。基于Imar,我有一个CollectionBase
类,我的所有列表类型属性都将从中继承。
public abstract class CollectionBase<T> : Collection<T>, IList<T> {
protected CollectionBase() : base(new List<T>()) {}
protected CollectionBase(IList<T> initialList) : base(initialList) {}
protected CollectionBase(CollectionBase<T> initialList) : base(initialList) {}
public void Sort(IComparer<T> comparer) {
var list = (List<T>) Items;
if (list != null) {
list.Sort(comparer);
}
}
public void Sort() {
var list = (List<T>) Items;
if (list != null) {
list.Sort();
}
}
public void AddRange(IEnumerable<T> collection) {
if (collection == null) {
throw new ArgumentNullException("collection", "Parameter collection is null.");
}
foreach (var item in collection) {
Add(item);
}
}
}
然后,我有了另一个类,我想使用ASP.NET Identity
的代码实践使其尽可能通用。
// this class is instantiated with 2 types, one for the Id property for emails and one for the Id property for owner
public class Emails<TKey, TOwner> : CollectionBase<Email<TKey, TOwner>> {
public Emails() {}
public Emails(IList<Email<TKey, TOwner>> initialList) : base(initialList) {}
public Emails(CollectionBase<Email<TKey, TOwner>> initialList) : base(initialList) {}
}
我现在正试图创建一个从泛型继承的类作为快捷方式,类似于ASP.NET Identity
的做法,它从泛型继承,具有假定的类型。
public class Emails : Emails<String, String> {
public Emails() {}
public Emails(IList<Email> initialList) : base(initialList) {
// getting error on the 'base' call since there is no signature similar to Emails(IList<Email> initialList)
// how can I convert the parameter IList<Email> initialList to an IList<Email<String, String>>
}
public Emails(CollectionBase<Email> initialList) : base(initialList) {
// getting error on the 'base' call since there is no signature similar to Emails(CollectionBase<Email> initialList)
// how can I convert the parameter CollectionBase<Email> initialList to a CollectionBase<Email<String, String>>
}
}
以防万一,这里是Email
类
public class Email : Email<String> {
public Email(String address, String ownerId)
: base(address, ownerId) {}
}
public class Email<TKey> : Email<TKey, String> {
public Email(String address, String ownerId)
: base(address, ownerId) {}
}
public class Email<TKey, TOwner> : DomainEntity<TKey>, IHasOwner {
public Email(String address, TOwner ownerId)
: this() {
Address = address;
OwnerId = ownerId;
}
protected Email() {}
public String Address { get; set; }
public TOwner OwnerId { get; set; }
public Person Owner { get; set; }
}
问题
正如我在评论中所指出的,我遇到的问题是基类没有Emails(IList<Email> initialList)
和Emails(CollectionBase<Email> initialList)
的签名方法,当然它们也不应该有。我知道我不应该像上面那样调用base
,但我把它留在了那里,以防有一个非常简单的代码可以在可以调用的地方进行转换,而不必在方法中编写额外的代码。
问题
如何将参数类型IList<Email> initialList
和CollectionBase<Email> initialList
分别"转换"为List<Email<String, String>>
和CollectionBase<Email<String, String>>
?
潜在答案
我可能自己创造了答案,但我还不够熟悉,不知道这是怎么做的。如果不是,请提供我应该做的任何更改和/或提供一个完全不同的答案。
这是我玩了一会儿之后的课。
public class Emails : Emails<String, String> {
public Emails() {}
public Emails(IList<Email> initialList) : base((IList<Email<String, String>>)initialList.Select(email => new Email<String, String>(email.Address, email.OwnerId))) {}
public Emails(CollectionBase<Email> initialList) : base((CollectionBase<Email<String, String>>)initialList.Select(email => new Email<String, String>(email.Address, email.OwnerId))) {}
}
您可以做一个扩展方法来实现强制转换吗。无法执行隐式强制转换,因为编译器不知道如何将Generics.List转换为Generics.List.
要解决您的问题,请尝试:
我将方法更改为调用基类中的方法。
public class Emails : Emails<String, String>
{
public Emails()
{
}
public Emails(IList<Email> initialList) : base(initialList.ToMyList())
{
// getting error on the 'base' call since there is no signature similar to Emails(IList<Email> initialList)
// how can I convert the parameter IList<Email> initialList to an IList<Email<String, String>>
}
public Emails(CollectionBase<Email> initialList) : base(initialList.ToMyCollection())
{
// getting error on the 'base' call since there is no signature similar to Emails(CollectionBase<Email> initialList)
// how can I convert the parameter CollectionBase<Email> initialList to a CollectionBase<Email<String, String>>
}
}
我用一个扩展方法来转换你的类:
public static class ExtensionListEmail
{
public static IList<Email<string, string>> ToMyList(this IList<Email> list)
{
return new List<Email<string, string>>(list);
}
public static CollectionBase<Email<string, string>> ToMyCollection(this CollectionBase<Email> collection)
{
return new Emails(collection);
}
}
我希望我帮过忙。
在我看来,没有必要创建Emails
快捷方式。实现Emails
快捷方式如下:
public class StringList : List<string>
{
}
这意味着为了使用List对象,我们为它创建了一个专用的类。但实际上,我们大多数时候并没有这样做。我们所做的如下:
var stringList = new List<string>();
所以,如果您废弃了Emails
快捷方式,您就不会有问题了。此外,你可以使用所有其他类如下:
var emails = new Emails<string, string>();
emails.Add(new Email("key", "ownerId"));
当然,实现这一点的前提是Emails
类只是一条捷径。如果您需要在该类中实现一些特定的函数,这些函数对应于它使用的泛型类型,那就另当别论了。
到目前为止,这是我正在使用的解决方案,直到有人能够使Gibran Silvia的答案对这两个函数都更通用。
public class Emails : Emails<String, String> {
public Emails() {}
public Emails(IList<Email> initialList) : base((IList<Email<String, String>>) initialList.Select(email => new Email<String, String>(email.Address, email.OwnerId))) {}
public Emails(CollectionBase<Email> initialList) : base((CollectionBase<Email<String, String>>) initialList.Select(email => new Email<String, String>(email.Address, email.OwnerId))) {}
}