理解泛型课程 [英] understand generic class
问题描述
我对泛型课程不强。假设我们有一个班级。
class 约会
{
public Guid UniqueId { get ; set ; }
}
和一个扩展类:
public static class ExtendReceive< T> 其中 T:约会
{
public static void TryReceive< T>(此 BufferBlock< T> bufferBlock, int count)
{
try
{
for ( var i = 0 ; i < count; i ++)
{
T item;
if (bufferBlock.TryReceive( out item))
{
呼叫d = new Call();
d.RunScript< T>((T)item);
}
其他
{
break ;
}
}
}
最后
class 致电
{
internal void RunScript< T>(T t)
{
var x = t.UniqueId;
}
但这行不对:
var x = t.UniqueId; // 错误
我们也称之为扩展方法也有错误:
public static BufferBlock<约会> m_Queue = new BufferBlock< Appointment>();
m_Queue.TryReceive( 4 ); // 错误
最好的重载方法匹配...有一些无效的参数。
感谢您的建议。
你开始了正确的,然后弄得一团糟。编译器如何知道x
的成员UniqueId
?
您需要在泛型类ExtendReceive
中执行此操作。在这个类中,编译器知道参数是约会
(这个确切的类型或派生自这个类),由于约束其中T:约会
。这是这些约束背后的整个想法。
如果出现第二个错误,我声明System.Threading.Tasks.Dataflow.BufferBlock .TryReceive
(感谢澄清)显示了这个签名( http://msdn.microsoft.com/en-us/library/hh194808%28v=vs.110%29.aspx [ ^ ]):
public static bool TryReceive< TOutput>(
此 IReceivableSourceBlock< TOutput>来源,
out TOutput item
)
我不知道你为什么认为有一个同名的方法期望一个整数参数。此外,此方法是静态的,您不能在m_Queue
上调用它,调用语法将是BufferBlock.TryReceive(/ * ... * / )
。在这里,你遇到了编程基础知识的问题,甚至没有特别与.NET泛型有关。
-SA
您声明了一个具有Generic类型的静态类。静态类无法实例化,你最终会使用类名,这将减少声明扩展方法的目的。
而不是在静态类上声明泛型放入对扩展方法本身的约束。
public static class ExtendReceive
{
public static void TryReceive< t>(此 BufferBlock< t> bufferBlock,< span class =code-keyword> int count) where T:约会
{
尝试
{
for ( var i = 0 跨度>;我< count; i ++)
{
T item;
if (bufferBlock.TryReceive( out item))
{
呼叫d = new Call();
d.RunScript< t>((T)item);
}
其他
{
break ;
}
}
}
< / t > < / t < span class =code-keyword>> < / t >
如果是课堂电话,您需要决定是否需要整个调用中的泛型类型引用或仅适用于RunScript方法并相应地添加约束
class 调用
{
内部 void RunScript< t>(T t)< span class =code-sdkkeyword> where T:约会
{
var x = t.UniqueId;
}
< / t > 跨度>
I am not strong on generic class. Say we have a class.
class Appointment
{
public Guid UniqueId { get; set; }
}
And an extensiton class:
public static class ExtendReceive<T> where T:Appointment
{
public static void TryReceive<T>(this BufferBlock<T> bufferBlock, int count)
{
try
{
for (var i = 0; i < count; i++)
{
T item;
if (bufferBlock.TryReceive(out item))
{
Call d = new Call();
d.RunScript<T>((T)item);
}
else
{
break;
}
}
}
And finally
class Call
{
internal void RunScript<T>(T t)
{
var x = t.UniqueId;
}
However this line is wrong:
var x = t.UniqueId; //error
Also we call this extension method also got error:
public static BufferBlock<Appointment> m_Queue = new BufferBlock<Appointment>();
m_Queue.TryReceive(4); // error as well
The best overload method match ...has some invalid arguments.
Thanks for advice.
You started correctly, and then made a mess. How a compiler can know thatx
has the memberUniqueId
?
You need to do it as in the generic classExtendReceive
. In this class, the compiler knows that the parameter isAppointment
(this exact type or derived from this class), due to the constraintwhere T: Appointment
. This is the whole idea behind those constraints.
In case of second error, I the declaration ofSystem.Threading.Tasks.Dataflow.BufferBlock.TryReceive
(thanks for clarification) shows this signature (http://msdn.microsoft.com/en-us/library/hh194808%28v=vs.110%29.aspx[^]):
public static bool TryReceive<TOutput>( this IReceivableSourceBlock<TOutput> source, out TOutput item )
I have no idea why did you decide that there is a method with the same name expecting an integer argument. Moreover, this method is static, you cannot possibly call it onm_Queue
, the call syntax would beBufferBlock.TryReceive(/* ... */)
. Here, you have a problem with programming basics, not even specifically related to .NET generics.
—SA
You declared a static class with Generic type. Static classes cannot be instantiated and you will end up using the class name which will diminish the purpose of declaring an extension method.
Instead of declaring generic on static class put the constraint on the extension method itself.
public static class ExtendReceive { public static void TryReceive<t>(this BufferBlock<t> bufferBlock, int count) where T:Appointment { try { for (var i = 0; i < count; i++) { T item; if (bufferBlock.TryReceive(out item)) { Call d = new Call(); d.RunScript<t>((T)item); } else { break; } } } </t></t></t>
In case of class Call, you need to decide whether you need the generic type reference throughout the call or only for the method RunScript and accordingly add constraint
class Call { internal void RunScript<t>(T t) where T:Appointment { var x = t.UniqueId; } </t>
这篇关于理解泛型课程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!