理解泛型课程 [英] understand generic class

查看:76
本文介绍了理解泛型课程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对泛型课程不强。假设我们有一个班级。

  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 that x has the member UniqueId?

You need to do it as in the generic class ExtendReceive. In this class, the compiler knows that the parameter is Appointment (this exact type or derived from this class), due to the constraint where T: Appointment. This is the whole idea behind those constraints.

In case of second error, I the declaration of System.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 on m_Queue, the call syntax would be BufferBlock.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆