【问题标题】:C# overloading a generic function [duplicate]C#重载泛型函数[重复]
【发布时间】:2014-10-02 17:40:44
【问题描述】:

我正在尝试使用特定方法重载通用方法。但是他不会去具体的类型化方法,他会采用不会实现的泛型方法。

public static class Functions<TE, TC, TG>
     where TE : Entity, IExternalConexioEntity
     where TC : class, IInternalConexioEntity, IObjectState
     where TG : ConexioEntity
{

public static TG ConvertToEntity(TC conexioEntity)
{
    throw new Exception("Type not supported(" + conexioEntity.GetType() + ")");
}

public static Contact ConvertToEntity(ConexioContact synccontact)
{

}
}

方法调用:

result.Add(ConvertEntity(synchronizationContact));

而且syncrhonizationContact也是一个泛型类型where TC : class, IInternalConexioEntity, IObjectState。所以实际的类型是 ConexioContact。

但他没有使用第二种方法,我的值是 ConexioContact 类型。

Conexio.Data.Entities.Conexio.ConexioContact
System.AggregateException: One or more errors occurred. ---> System.Exception: Type not supported(Conexio.Data.Entities.Conexio.ConexioContact)
   at Conexio.Core.Orchestration.Functions`3.ConvertToEntity(TC conexioEntity) in 
d:\TeamFoundation\Sources\Conexio\Conexio.Core.Orchestration\Functions.cs:line 187
   at Conexio.Core.Orchestration.Contacts.Doubtfuls.SearchDoubtfuls`3.ConvertEntity(TC entity) in d:\TeamFoundation\Sources\Conexio\Conexio.Core.Orchestration\Contacts\Doubtfuls\SearchDoubtfuls.cs:line 107
   at Conexio.Core.Orchestration.Contacts.Doubtfuls.SearchDoubtfuls`3.<SearchAsync>d__5.MoveNext() in d:\TeamFoundation\Sources\Conexio\Conexio.Core.Orchestration\Contacts\Doubtfuls\SearchDoubtfuls.cs:line 61
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Conexio.Core.Orchestration.Contacts.ConexioEntityBL`3.<SearchDoubtfulsAsync>d__28.MoveNext() in d:\TeamFoundation\Sources\Conexio\Conexio.Core.Orchestration\Contacts\ConexioEntityBL.cs:line 323
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   at Conexio.Core.Orchestration.Test.Doubtfuls.SearchContactsTest.TestSearch4() in d:\TeamFoundation\Sources\Conexio\Conexio.Core.Orchestration.Matching.Test\Doubtfuls\SearchContactsTest.cs:line 90
---> (Inner Exception #0) System.Exception: Type not supported(Conexio.Data.Entities.Conexio.ConexioContact)
   at Conexio.Core.Orchestration.Functions`3.ConvertToEntity(TC conexioEntity) in d:\TeamFoundation\Sources\Conexio\Conexio.Core.Orchestration\Functions.cs:line 187
   at Conexio.Core.Orchestration.Contacts.Doubtfuls.SearchDoubtfuls`3.ConvertEntity(TC entity) in d:\TeamFoundation\Sources\Conexio\Conexio.Core.Orchestration\Contacts\Doubtfuls\SearchDoubtfuls.cs:line 107
   at Conexio.Core.Orchestration.Contacts.Doubtfuls.SearchDoubtfuls`3.<SearchAsync>d__5.MoveNext() in d:\TeamFoundation\Sources\Conexio\Conexio.Core.Orchestration\Contacts\Doubtfuls\SearchDoubtfuls.cs:line 61
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Conexio.Core.Orchestration.Contacts.ConexioEntityBL`3.<SearchDoubtfulsAsync>d__28.MoveNext() in d:\TeamFoundation\Sources\Conexio\Conexio.Core.Orchestration\Contacts\ConexioEntityBL.cs:line 323<---

【问题讨论】:

  • 你是怎么调用这个方法的?
  • 我在帖子中添加了调用方法。
  • @PanagiotisKanavos 我喜欢 Marc 的解释和示例。不错(我认为适用)链接。
  • @Ghost 编译器不知道实体是联系人。我认为您应该改用多态性(即使用虚拟方法而不是模板继承)。这两个概念重叠。

标签: c# generics


【解决方案1】:

您要做的不是超载。它称为泛型特化,在 C# 中不受支持。有一些brittle workarounds 仅在具体类型已知在编译时 时才起作用。

如果您使用ConexioContact-typed 参数进行调用,编译器会知道第二种方法更具体。

如果您传递一个更通用的参数,例如IConexioContactobject,编译器将看到它没有特定的方法,但它可以使用通用方法创建一个。所以ConvertToEntity&lt;IConexioContact&gt; 战胜了ConvertToEntity(ConexioContact),你得到了一个例外。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-14
    • 2015-05-23
    • 2018-04-27
    • 2016-05-28
    • 1970-01-01
    • 2017-04-01
    相关资源
    最近更新 更多