2016-11-28 153 views
-2

我知道标题可能有点不清楚,所以我会解释我正在尝试做什么。是否可以使用/提取泛型使用的类型来定义第二个泛型的类型?

请注意,这是围绕语言的功能更多的教育原因。换句话说如果这是可能的,而不是应该这是要走的路。

考虑下面的通用类:

public class Foo<TId> 
{ 
    TId Id { get; set; } 
} 

现在基于上述考虑具体子类。这里有两个例子使用“廉政”和“串” ......

public class IntFoo : Foo<int> 
{ 
} 

public class StrFoo : Foo<string> 
{ 
} 

最后一个通用的,需要一个富作为一个类型参数,并从左心耳这需要从富的类型参数继承。

public class BaseClass<TFoo, TFooId> : Laa<TFooId> 
{ 
} 

public class Laa<TFooId> 
{ 
} 

这里是你会怎么做基于一个int和字符串的一个,但除了IntFoo和StrFoo注意,我也必须定义int和富明确...

public class IntFinal : BaseClass<IntFoo, int> 
{ 
    char somePropSpecificToIntFinal{ get; set; } 
} 

public class StrFinal : BaseClass<StrFoo, string> 
{ 
    char somePropSpecificToStrFinal{ get; set; } 
} 

请注意,这些'final'类是具有自己的属性的具体类型,不能简化为需要类型的泛型(即使用泛型与单个类型T,然后子类化另一个通用Foo和T作为其论据。

我不知道是如果有办法有该类型推断所以它可以写成这样的...

public class IntFinal : BaseClass<IntFoo> 
{ 
} 

public class StrFinal : BaseClass<StrFoo> 
{ 
} 

...并有从富指定的通用隐含左心耳类型。这是我想要的一个伪代码示例。

public class BaseClass<TFoo> : Laa<TFoo.IdType> 
{ 
} 

那么在C#中可能吗?

请注意,如果这不能用类来完成,可以用接口来完成吗?

考虑这个...

interface IFoo 
{ 
    Type FoosType { get; } 
} 

public class Foo<TId> : Foo 
{ 
    TId Id { get; set; } 

    Type FoosType { get{ return TId } } 
} 

然后做此...

public class BaseClass<TFoo> : Laa<TFoo.FoosType> 
where TFoo : Foo 
{ 
} 

(注:FoosType必须是静态的技术,你不能继承使用静态如此反复,这是伪代码。)

如果您将TFoo限制为IFoo,那么在定义Laa时可以使用'FoosType'作为类型说明符吗?

+0

我想我已经看到了一些这样的实现。但不确定。 – Prajwal

+0

我想你应该能够处理这与Where子句(其中IntFoo:Int32)或(其中IntFoo:INumeric) - 想法是[MSDN](https://msdn.microsoft.com/cs-cz/library/ bb384067%28v = vs.100%29.aspx?f = 255&MSPPError = -2147217396) – Tatranskymedved

+0

不,我不会将其限制为数字。我试图得到任何类型的Foo 正在使用。为了清楚起见,我会更新这个问题。 – MarqueIV

回答

0

你不能这样做基于C#规范。类型推断当前仅适用于方法,不适用于类型(类似您的案例)

第二条规则打破您的需要结果是您不能指定一个泛型类型参数并推断另一个,它是提供全部或全部案例的方法。

C#规格:

1.6.3类型参数

当使用泛型类,类型参数必须设置用于每个类型参数的

+0

但我不明白要提供它吗?我不会因为你提到的原因而推断任何事情。换句话说,如果我定义了一个泛型,我可以获取传递给它的类型以传递给基类。其实......我只是有一个主意!回到一分钟... – MarqueIV

+0

不!没有工作! :) 呃,好吧。你能做什么?! – MarqueIV

+0

@MarqueIV不,你没有明确提供它。如果一个类需要2个类型参数,则必须指定这两个参数:'Foo '。你不能指定'T'并且编译器通过其他方式推断'V'。这是语言规范。 – user3185569

-1

的问题是不非常具体,并且不清楚实际的限制和要求是什么。这说&hellip;

只有泛型方法才会出现类型推断,而不是泛型类型。因此,从字面上理解你的问题,答案是否定的,没有办法推断这种类型。

什么可能会为你工作是在类定义使用Foo<TId>而不是IntFoo

class BaseClass<TFooId> : Laa<TFooId> 
{ 
    public Foo<TFooId> Method() { ... } 
} 

(当然,你可以在任何地方申请酌情类型:字段,属性类型等)

iee代替编码BaseClass类型具有两个类型参数,只要使用能唯一地定义您使用的Foo<TFooId>基类的有趣/有用的元素之一,并且然后使用该基本类型,而不是更衍生IntFoo

在你的例子中,你对TFoo类没有限制,所以它不像BaseClass<TFoo, TFooId>即使是来自Foo<TId>的基类型成员也可以使用。但即使你的意图是将TFoo限制为Foo<TFooId>,看起来你可能并不需要指定该类型。

如果上述内容没有用,那么您需要为您的问题添加更多的细节,以便准确解释需要什么。还要考虑到人们可能已经走上了这条路,如果你不需要表达你的问题,那么你需要的是认为,而不是你在更高的层次上使用它,你可能会发现现有的问题堆栈溢出或其他地方的文章已经解决了这个更广泛的问题。

至少,如果您无法亲自找到这样的参考文献,那么用这种方式表达您的问题可能会更快地产生更好的答案。请参阅XY Problem

+0

虽然我很欣赏你的答案,但我已经解决了为什么我不能使用你所陈述的基类实现(使用单一类型而不是两类泛型)。至于解释具体细节,问题会更长而不是真正的我以后是什么,看看你是否可以从通用继承的东西中提取类型。我相信答案是否定的,但总是有些语言的某些部分不知道别人在哪里,所以我问。谢谢你的批评。我们只是在看两件不同的事情。 – MarqueIV