我有一个名为Identifiable<TId>
的接口,它包含给定类型的单个属性Id。我想创建一个泛型类,将其中一个作为类型参数。它应该是通用的,因为我想返回具体类型,从其中调用其他泛型方法并使用typeof(T)
之类的东西。
这很好用:
public class ClassName<T, TId> where T : Identifiable<TId>
问题是调用代码必须传递两种类型。例如。 new ClassName<Person, int>()
我想知道是否在.net 3.5中有一些方法可以写这个,以便可以用T推断TId?允许来电者只做new ClassName<Person>()
?
答案 0 :(得分:2)
根据您问题的性质,我猜测您的ClassName并不依赖于Identifiable中需要TId的任何方法(否则您需要该类型。)如果是这样的话,在这种情况下,一个常见的解决方案是创建一个非通用的基本接口,所有方法都不需要TId类型。然后你有:
interface Identifiable<TId> : Identifiable //Not a standard interface name, btw
,您的约束变为:
public class ClassName<T> where T : Identifiable
假设您确实需要TId类型,但只是想简化构造语法,一个选项,如果您的构造函数采用Identifiable的实例(例如您的示例中的Person),则将构造函数更改为工厂方法:
public static ClassName<T, TId> FromIdentifiable<T,TId>(T identifiable) where T: Identifiable<TId>
上面应该允许编译器推断出类型,并根据参数的类型给出更短的语法。
答案 1 :(得分:1)
没有。您需要为Identifiable<>
提供类型参数;如果不在类声明中声明参数,你怎么能这样做:
public class ClassName<T> where T : Identifiable<?WhatDoWePutHere?>
答案 2 :(得分:1)
AFAIK,where
子句无法实现。您可能希望使用代码合同(例如在.Net 4中)并添加
Contract.Requires(T is Identifiable<TId>);
代码。我不知道是否有任何方法可以在.Net 3.5中强制执行此操作。
答案 3 :(得分:1)
如果您的课程的大多数用途都是ClassName<Person, int>
形式,其中T类型(人物)的大部分时间都不同,但TId类型几乎总是int
,您可以提供部分解析的类,它提供TId类型但保持T类型不绑定。这样做的主要缺点是你将拥有多个必须具有不同名称的类。
public class BaseClassName<T, TId> where T: Identifiable<TId>
{ }
public class ClassName<T> : ClassName<T, int>
{ }
var x = new ClassName<Person>();
对于不希望int作为TId的情况较少的情况,那么arity 2类仍然可用:
var y = new BaseClassName<Person, int>()