C# 无法从类型转换<;类型>;输入<;IType>;

C# 无法从类型转换<;类型>;输入<;IType>;,c#,generics,C#,Generics,我正在尝试实现一个通用的Excel导出 我已经创建了两个接口IData和IDataListIData提供了一个函数来获取转换为数组的数据,并提供了一个函数来获取属性的相应名称 接口 public interface IData { string[] GetData(); } public interface IDataList<IData> : IList<IData> { string[] GetHeader(); } 类和接口需要稍作更改 publ

我正在尝试实现一个通用的Excel导出

我已经创建了两个接口
IData
IDataList
IData
提供了一个函数来获取转换为数组的数据,并提供了一个函数来获取属性的相应名称

接口

public interface IData
{
    string[] GetData();
}

public interface IDataList<IData> : IList<IData>
{
    string[] GetHeader();
}
类和接口需要稍作更改

public interface IHasHeader { string[] GetHeader(); }
public class DataList : List<Data>, IHasHeader { }
public class Data : IData { }

我没有添加解决方案所需的声誉。如果有人将其转换为我愿意接受的解决方案。

您可以编写一个方法来获取任何列表,方法是告诉它获得一个
IEnumerable
,即
list
IEnumerable
的基本类型。这是非泛型类型。如果在这里使用
IList
,则需要显式指定类型

请参见下面的示例,了解如何在方法中使用IEnumerable并检查它:

private class MyClass { }
private class MyClassWithInterface : IMyClass { }
private interface IMyClass { }

static void Main(string[] args)
{
    ITakeLists(new List<MyClass>()); // it is
    ITakeLists(new List<MyClassWithInterface>()); // isInstanceOf
    ITakeLists(new List<int>()); // it is not
    //ITakeLists(new MyClass()); // Error, is not derived from IEnumerable
}

private static void ITakeLists(IEnumerable myList)
{
    if (myList is List<MyClass>)
        Console.WriteLine("it is");
    else if(typeof(IMyClass).IsAssignableFrom(myList.GetType().GetGenericArguments()[0]))
        Console.WriteLine("isInstanceOf");
    else
        Console.WriteLine("it is not :(");
}
私有类MyClass{}
私有类MyClassWithInterface:IMyClass{}
专用接口IMyClass{}
静态void Main(字符串[]参数)
{
ITakeLists(new List());//它是
ITakeLists(new List());//isInstanceOf
ITakeLists(new List());//它不是
//ITakeLists(new MyClass());//错误,不是从IEnumerable派生的
}
私有静态无效ITakeLists(IEnumerable myList)
{
如果(我的列表是列表)
Console.WriteLine(“它是”);
else if(typeof(IMyClass).IsAssignableFrom(myList.GetType().GetGenericArguments()[0]))
控制台写入线(“isInstanceOf”);
其他的
Console.WriteLine(“它不是:(”);
}

您可以编写一个方法来获取任何列表,方法是告诉它获取一个
IEnumerable
list
IEnumerable
的基类型。这是一个非泛型类型。如果您在这里获取
IList
,则需要显式指定类型

请参见下面的示例,了解如何在方法中使用IEnumerable并检查它:

private class MyClass { }
private class MyClassWithInterface : IMyClass { }
private interface IMyClass { }

static void Main(string[] args)
{
    ITakeLists(new List<MyClass>()); // it is
    ITakeLists(new List<MyClassWithInterface>()); // isInstanceOf
    ITakeLists(new List<int>()); // it is not
    //ITakeLists(new MyClass()); // Error, is not derived from IEnumerable
}

private static void ITakeLists(IEnumerable myList)
{
    if (myList is List<MyClass>)
        Console.WriteLine("it is");
    else if(typeof(IMyClass).IsAssignableFrom(myList.GetType().GetGenericArguments()[0]))
        Console.WriteLine("isInstanceOf");
    else
        Console.WriteLine("it is not :(");
}
私有类MyClass{}
私有类MyClassWithInterface:IMyClass{}
专用接口IMyClass{}
静态void Main(字符串[]参数)
{
ITakeLists(new List());//它是
ITakeLists(new List());//isInstanceOf
ITakeLists(new List());//它不是
//ITakeLists(new MyClass());//错误,不是从IEnumerable派生的
}
私有静态无效ITakeLists(IEnumerable myList)
{
如果(我的列表是列表)
Console.WriteLine(“它是”);
else if(typeof(IMyClass).IsAssignableFrom(myList.GetType().GetGenericArguments()[0]))
控制台写入线(“isInstanceOf”);
其他的
Console.WriteLine(“它不是:(”);
}

请您详细说明为什么要将泛型添加到
IDataList
?我发现您在接口定义本身中没有使用此泛型类型,这是多余的。这是我看到的泛型
类型的最常见错误
不是
IType
它们是不同的(尽管它看起来应该能工作),你所能期望的最好的是一个方便的
IType
,它将限制它的使用。我认为这个问题需要重新思考。没有一个更具体的例子,很难知道你应该用哪种方式来做这件事,比如说我有一个
列表
?我应该把它转换成
列表
?答案是否定的-从那时起我就可以
添加另一个结果。这显示了一般原则。
A
不能转换为
A
。很抱歉我有一个拼写错误。当继承层次结构中存在泛型时,方便=共变多态性不起作用。请详细说明为什么要将泛型添加到
IDataList
?我发现您没有在接口定义本身中使用此泛型类型,这使得它变得多余。这是我在泛型
类型
中看到的最常见错误,它不是
IType
它们是不同的(尽管看起来它应该可以工作),你所能期望的最好的是一个方便的
IType
,它将限制它的使用。我认为这个问题需要重新思考。没有一个更具体的例子,很难知道你应该用哪种方式来做这件事,比如说我有一个
列表
?我应该把它转换成
列表
?答案是否定的-从那时起我就可以
添加另一个水果。这显示了一般原则。
A
不能转换为
A
。很抱歉我有一个拼写错误。方便=CovarientPolymorphics在继承层次结构中的某个地方有泛型时不起作用。我可以使用枚举而不是列表。但是我需要函数
GetHeader()
。因此,我尝试从可枚举对象继承:
公共接口IDataList:IEnumerable
对于实现,我使用了一个列表
公共类DataList:list,IDataList
。参数类型保持不变
公共void CreateDocument(IDataList数据)
。同样的例外是:无法从
DataList
转换为
IDataList
。关键是,如果泛型参数是其他类型,则无法从任何其他类型继承。
TypeA
永远不能是
TypeA
。为什么不直接从另一个接口
IHasH派生
DataList
-类呢eader
?然后,如果您在这里只需要此方法,您可以通过此接口
CreateDocument(iHaHeader list)
在该对象上调用它。我可以使用枚举而不是列表。但是我需要函数
GetHeader()
。因此,我尝试从可枚举对象继承:
公共接口IDataList:IEnumerable
对于实现,我使用了一个列表
公共类DataList:list,IDataList
。参数类型保持不变
公共void CreateDocument(IDataList数据)
。同样的例外情况是:无法从
DataList
转换为
IDataList
。关键是,如果泛型参数是其他类型,则不能从任何其他类型继承。
TypeA
永远不能是
TypeA
public interface IHasHeader { string[] GetHeader(); }
public class DataList : List<Data>, IHasHeader { }
public class Data : IData { }
public DataList data = new DataList();
// data.Add(new Data(){ ... })
CreateDocument(data.GetHeader(), data.Select(x => x.GetData()));
private class MyClass { }
private class MyClassWithInterface : IMyClass { }
private interface IMyClass { }

static void Main(string[] args)
{
    ITakeLists(new List<MyClass>()); // it is
    ITakeLists(new List<MyClassWithInterface>()); // isInstanceOf
    ITakeLists(new List<int>()); // it is not
    //ITakeLists(new MyClass()); // Error, is not derived from IEnumerable
}

private static void ITakeLists(IEnumerable myList)
{
    if (myList is List<MyClass>)
        Console.WriteLine("it is");
    else if(typeof(IMyClass).IsAssignableFrom(myList.GetType().GetGenericArguments()[0]))
        Console.WriteLine("isInstanceOf");
    else
        Console.WriteLine("it is not :(");
}