Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.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# 如何约束泛型方法的嵌套泛型类型_C#_Generics_Nested Generics_Generic Constraints - Fatal编程技术网

C# 如何约束泛型方法的嵌套泛型类型

C# 如何约束泛型方法的嵌套泛型类型,c#,generics,nested-generics,generic-constraints,C#,Generics,Nested Generics,Generic Constraints,我试图创建一个方法,该方法基于给定的泛型类型从数据库返回数据 接口:(此定义编译) 公共接口位置 托德在哪里 鞑靼人在哪里 其中TOrderPosition:IOrderPosition { long?id{get;set;} 扭序{get;set;} 鞑靼文{get;set;} 列出子位置{get;set;} } 可能的具体实现:(此定义编译) public类OrderPosition:IOrderPosition { 公共long?id{get;set;} 公共秩序{get;set;} 公

我试图创建一个方法,该方法基于给定的泛型类型从数据库返回数据

接口:(此定义编译)

公共接口位置
托德在哪里
鞑靼人在哪里
其中TOrderPosition:IOrderPosition
{
long?id{get;set;}
扭序{get;set;}
鞑靼文{get;set;}
列出子位置{get;set;}
}
可能的具体实现:(此定义编译)

public类OrderPosition:IOrderPosition
{
公共long?id{get;set;}
公共秩序{get;set;}
公共物品文章{get;set;}
公共列表子位置{get;set;}
}
尝试基于接口编写泛型方法:(此定义未编译)

公共列表GetOrderPositionOfOrder(长?id)
托德在哪里
塔提克在哪里
其中TOrderPosition:IOrderPosition
{
..
}
错误:

'DataSourceOrder.GetOrderPositionOfOrder<TOrderPosition>()' does not define type parameter 'TOrder'
'DataSourceOrder.GetOrderPositionOfOrder<TOrderPosition>()' does not define type parameter 'TArticle'
The type or namespace name 'TOrder' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'TArticle' could not be found (are you missing a using directive or an assembly reference?)
List<OrderPosition> positions = GetOrderPositionOfOrder<OrderPosition>(5);
List<TransferOrderPosition> transferPositions = GetOrderPositionOfOrder<TransferOrderPosition>(5);
“DataSourceOrder.GetOrderPositionOfOrder()”未定义类型参数“TOrder”
“DataSourceOrder.GetOrderPositionOfOrder()”未定义类型参数“TArticle”
找不到类型或命名空间名称“TOrder”(是否缺少using指令或程序集引用?)
找不到类型或命名空间名称“TArticle”(是否缺少using指令或程序集引用?)
这样使用:

'DataSourceOrder.GetOrderPositionOfOrder<TOrderPosition>()' does not define type parameter 'TOrder'
'DataSourceOrder.GetOrderPositionOfOrder<TOrderPosition>()' does not define type parameter 'TArticle'
The type or namespace name 'TOrder' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'TArticle' could not be found (are you missing a using directive or an assembly reference?)
List<OrderPosition> positions = GetOrderPositionOfOrder<OrderPosition>(5);
List<TransferOrderPosition> transferPositions = GetOrderPositionOfOrder<TransferOrderPosition>(5);
List positions=GetOrderPositionOfOrder(5);
列表transferPositions=GetOrderPositionOfOrder(5);

问题:

'DataSourceOrder.GetOrderPositionOfOrder<TOrderPosition>()' does not define type parameter 'TOrder'
'DataSourceOrder.GetOrderPositionOfOrder<TOrderPosition>()' does not define type parameter 'TArticle'
The type or namespace name 'TOrder' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'TArticle' could not be found (are you missing a using directive or an assembly reference?)
List<OrderPosition> positions = GetOrderPositionOfOrder<OrderPosition>(5);
List<TransferOrderPosition> transferPositions = GetOrderPositionOfOrder<TransferOrderPosition>(5);
为什么这是为接口编译的,而不是为方法编译的

我希望两者都能成功,或者两者都会失败。我假设编译可以从为TOrderPosition提供的类型推断TOrder和TArticle的类型,TOrderPosition定义了文章和订单的具体类型


我想知道为什么会发生这种情况,以及我是否可以以及如何在不必明确指定所有类型的情况下解决问题。

在接口中,您将其定义为一个泛型,接受3种类型
TOrder、TArticle、TOrderPosition
,以便能够约束这些类型

您的方法只定义了一个类型,
TOrderPosition
,编译器无法从方法定义中的约束
,其中TOrderPosition:IOrderPosition
,推断您需要其他类型

您需要做的是以与接口相同的方式定义泛型方法上的所有类型:

public List<TOrderPosition> GetOrderPositionOfOrder<TOrder, TArticle, TOrderPosition>(long? id) 
 where TOrder : IOrder
 where TArticle : IArticle
 where TOrderPosition : IOrderPosition<TOrder, TArticle, TOrderPosition>
{
 ..
}
public static List<TOrderPosition> GetOrderPositionOfOrder<TOrder, TArticle, TOrderPosition>(long? id)
公共列表GetOrderPositionOfOrder(长?id)
托德在哪里
塔提克在哪里
其中TOrderPosition:IOrderPosition
{
..
}

查看错误:

“DataSourceOrder.GetOrderPositionOfOrder()”未定义类型参数“TOrder” “DataSourceOrder.GetOrderPositionOfOrder()”未定义类型参数“TArtile”

您引用的是不存在的类型参数。
您应该在方法中定义它们,就像在接口中定义它们一样:

public List<TOrderPosition> GetOrderPositionOfOrder<TOrder, TArticle, TOrderPosition>(long? id) 
 where TOrder : IOrder
 where TArticle : IArticle
 where TOrderPosition : IOrderPosition<TOrder, TArticle, TOrderPosition>
{
 ..
}
public static List<TOrderPosition> GetOrderPositionOfOrder<TOrder, TArticle, TOrderPosition>(long? id)
公共静态列表GetOrderPositionOfOrder(长?id)
这意味着调用该方法会有点难看:

var positions = GetOrderPositionOfOrder<Order, Position, OrderPosition>(5);
var transferPositions = GetOrderPositionOfOrder<TransferOrder, TransferArticle, TransferOrderPosition>(5);
var positions=GetOrderPositionOfOrder(5);
var transferPositions=GetOrderPositionOfOrder(5);
调用该方法时,必须提供所有类型参数,或者不提供(如果可以推断)。事情就是这样

为什么这是为接口编译的,而不是为方法编译的

那么,您是在
IOrderPosition
接口中声明
TOrder
TArticle
,而不是在
GetOrderPositionOfOrder
方法中声明的

您需要在方法声明中声明这些泛型参数:

public List<TOrderPosition> GetOrderPositionOfOrder<TOrder, TArticle, TOrderPosition>(long? id)
    where TOrder : IOrder
    where TArticle : IArticle
    where TOrderPosition : IOrderPosition<TOrder, TArticle, TOrderPosition>
{
    ...
}
您可以在
TOrder
TArticle
中使
IOrderPosition
协变:

interface IOrderPosition<out TOrder, out TArticle, TOrderPosition>
    where TOrder : IOrder
    where TArticle : IArticle
    where TOrderPosition : IOrderPosition<TOrder, TArticle, TOrderPosition>
{
    long? id { get; set; }
    TOrder order { get; }
    TArticle Article { get; }
    List<TOrderPosition> subPositions { get; set; }
}

执行此操作时,您可以进行如下调用
GetOrderPositionOfOrder(5)

但在方法中不定义TOrder和TArticle泛型参数,否则它会编译。对于你指定的所有三个类(TOrder、TArtile、TOrderPosition)@Evk,看看答案,很明显这不可能奏效,我只是希望编译器能从
OrderPosition
的类型中推断出缺失的类型,因为我不想列出所有类型(实际上不止这3个)感谢您为我展示了一种不需要显式声明所有类型的方法,因为这会剥夺整个解决方案的优雅性,遗憾的是,它可能不会帮助我,因为我需要它用于.Net 3.5 CF,我还需要设置那些方法无法读取的值them@Holly:Uhmm,那么也许您可以创建一个基本接口,如
iordersposition其中TOrderPosition:IOrderPosition
(如果需要,可以使用
id
subPositions
属性)和当前接口继承自此接口。然后可以这样声明方法:
GetOrderPositionOfOrder(long?id)TOrderPosition:IOrderPosition
感谢您的建议,我一直在考虑同样的事情,但不确定它是否值得麻烦,因为我需要反映所有类型和强制转换等等,现在我了解到嵌套泛型类型不会被推断(我假设),我甚至尝试提供OrderPosition的具体类型的实例作为参数,希望推断出所有类型参数,但这也不起作用-现在我有点怀念JAVAs
?extends ClassName
;-)