Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 转换对象或对象<;T>;反对<;T、 T>;_C#_Generics_Inheritance_Type Conversion - Fatal编程技术网

C# 转换对象或对象<;T>;反对<;T、 T>;

C# 转换对象或对象<;T>;反对<;T、 T>;,c#,generics,inheritance,type-conversion,C#,Generics,Inheritance,Type Conversion,我一直在关注Imar Spaanjaars关于的博客,并浏览了他的代码实践 // 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>> {

我一直在关注Imar Spaanjaars关于的博客,并浏览了他的代码实践

// 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) {}
}
我在继承和调用基方法方面遇到了一些麻烦

信息 首先让我向您展示基本代码。基于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
使用假定类型从泛型继承而来

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>>
    }
}
问题 正如我在评论中所指出的,我遇到的问题是基类没有用于
电子邮件(IList initialList)
电子邮件(CollectionBase initialList)
的签名方法,当然它们不应该有。我知道我不应该像上面的am那样调用
base
,但是我把它放在了那里,以防有一个非常简单的代码在可以调用的地方进行转换,而不必在方法中编写额外的代码

问题: 如何将参数类型
IList initialList
CollectionBase initialList
分别“转换”为
List
CollectionBase

潜在答案 我可能自己创造了答案,但我不太熟悉,不知道这是一种方法。如果不是,请提供我应该做的任何更改和/或提供完全不同的答案

这是我玩了一会儿后的课

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))) {}
}
公共类电子邮件:电子邮件{
公共电子邮件(){}
公共电子邮件(IList初始列表):基本((IList)初始列表。选择(email=>newemail(email.Address,email.OwnerId)){}
公共电子邮件(CollectionBase初始列表):基本((CollectionBase)初始列表。选择(email=>newemail(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>>
    }
}
公共类电子邮件:电子邮件
{
公开电邮()
{
}
公共电子邮件(IList initialList):基(initialList.ToMyList())
{
//“基本”呼叫中出现错误,因为没有类似于电子邮件的签名(IList Initialist)
//如何将参数IList initialList转换为IList
}
公共电子邮件(CollectionBase initialList):base(initialList.ToMyCollection())
{
//由于没有类似于电子邮件的签名(CollectionBase initialList),因此在“base”调用中获取错误
//如何将参数CollectionBase initialList转换为CollectionBase
}
}
我用扩展方法来转换你的类:

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);
    }
}
公共静态类扩展ListMail
{
公共静态IList ToMyList(此IList列表)
{
返回新列表(列表);
}
公共静态CollectionBase ToMyCollection(此CollectionBase集合)
{
返回新电子邮件(收集);
}
}

我希望我已经帮了忙。

在我看来,没有必要创建
电子邮件
快捷方式。实现
电子邮件
快捷方式如下:

public class StringList : List<string>
{
}
var stringList = new List<string>();

当然,前提是
Emails
类只是一种快捷方式。如果您需要在该类中实现与它使用的泛型类型相对应的某些特定函数,那就另当别论了。

到目前为止,这就是我正在使用的解决方案,直到有人能够使的答案对这两个函数都更加泛型

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))) {}
}
公共类电子邮件:电子邮件{
公共电子邮件(){}
公共电子邮件(IList初始列表):基本((IList)初始列表。选择(email=>newemail(email.Address,email.OwnerId)){}
公共电子邮件(CollectionBase初始列表):基本((CollectionBase)初始列表。选择(email=>newemail(email.Address,email.OwnerId)){}
}

代码中声明的电子邮件类型在哪里?@YuvalItzchakov,我添加了它。我是否必须迭代
初始列表中的每个对象,并使用正确的值创建一个我想要的类型的新对象?你不能直接转储
电子邮件
类吗?这是一个通用类,因此如果有人想使用它,
电子邮件
集合,对于
TKey
TOwner
,它们不受我的类型限制。
TKey
TOwner
分别是
Id
User
类的类型。如前所述,我想使用使用ASP.NET Identity的
ASP.NET实践。(见)试过了,似乎确实有效。正如@NicoSchertler所提到的,这被认为是缓慢的吗?这看起来是一个很好的解决方案。你能把它变成普通的吗?我不想为遵循此体系结构的每个类都创建一个新的扩展。i、 e:如果类型是
电子邮件
或者甚至是
地址
,那么我可以将
IList
作为泛型,但是我如何才能进行
收集
呢<代码>公共静态IList列表(此IList列表){返回新列表(列表);}
var emails = new Emails<string, string>();
emails.Add(new Email("key", "ownerId"));
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))) {}
}