2013-07-15 205 views
2

在一间非通用类中声明这两个方法,它们共享相同的签名:Func键委托声明的方法

private TypeResolverResult<T> TryRetrieveFromReusable<T>(TypeResolverConfiguration<T> typeResolverConfiguration) where T : class 
    { 
     return null; 
    } 

    private TypeResolverResult<T> BuildNew<T>(TypeResolverConfiguration<T> typeResolverConfiguration) where T : class 
    { 
     return null; 
    } 

如何创建一个表示这些方法签名的委托?

我似乎无法得到它,我想:

private Func<TypeResolverConfiguration<T>, TypeResolverResult<T>> _typeResolveFunc; 

但明显这不起作用,因为类是不通用的,我不能改变的。

感谢

UPDATE

这是多了还是少了什么,我需要:

public class Manager : ATypeResolver, IManager 
    { 
     private neeedDelegate; 


     public Manager(RuntimeConfiguration runtimeConfiguration, IList<RepositoryContainer> repositories) 
     { 
      if (runtimeConfiguration.WhatEver) 
      { 
       neeedDelegate = TryRetrieveFromReusable; 
      } 
      else 
      { 
       neeedDelegate = BuildNew; 
      } 
     } 

     public override TypeResolverResult<T> Resolve<T>() where T : class 
     { 
      //Want to avoid doing this: 

      if (runtimeConfiguration.WhatEver) 
      { 
       TryRetrieveFromReusable(new TypeResolverConfiguration<T>()); 
      } 
      else 
      { 
       BuildNew(new TypeResolverConfiguration<T>()); 
      } 

      //and have just this 

      neeedDelegate<T>(new TypeResolverConfiguration<T>()); 
     } 

     private TypeResolverResult<T> TryRetrieveFromReusable<T>(TypeResolverConfiguration<T> typeResolverConfiguration) where T : class 
     { 
      return null; 
     } 

     private TypeResolverResult<T> BuildNew<T>(TypeResolverConfiguration<T> typeResolverConfiguration) where T : class 
     { 
      return null; 
     } 
    } 
+1

在什么情况下你想使用它?如果什么都不是通用的,那么很难拥有泛型类型参数。即使类型不是因为调用者定义了类型,方法也可以是通用的。但是,除非包含类型是通用的,否则字段和属性不能是通用的。 – cadrell0

+0

@ cadrell0这些方法是通用的,但类不是通用的,它们有一个已定义的约束:class – Marco

+0

@ cadrell0是的,你是对的,回到开头。 – Marco

回答

1

更新从我所看到的,这样的做法应该工作,只要作为ATypeResolverwhere T : classResolve<T>

public class Manager : ATypeResolver, IManager 
{ 
    private bool tryRetrieveFromReusable; 

    public Manager(RuntimeConfiguration runtimeConfiguration, IList<RepositoryContainer> repositories) 
    { 
     this.tryRetrieveFromReusable = runtimeConfiguration.WhatEver; 
    } 
    public override TypeResolverResult<T> Resolve<T>() 
    { 
     var typeResolver = tryRetrieveFromReusable ? (TypeResolver<T>)TryRetrieveFromReusable : BuildNew; 

     return typeResolver(new TypeResolverConfiguration<T>()); 
    } 
} 

这将使用自定义的委托类型(Func像你应该也可以工作):

public delegate TypeResolverResult<T> TypeResolver<T>(
    TypeResolverConfiguration<T> typeResolverConfiguration) where T : class; 

如果你愿意,你可以在var typeResolver = ...线移动到它自己的方法,在逻辑中分离出来,并允许你可以从Resolve以上使用它。如果你这样做了,Resolve可能就像这样简单:return GetTypeResolver<T>()(new TypeResolverConfiguration<T>());

+1

你仍然不能这样做,因为包含的类不是通用的。 'T'从哪里来? – cadrell0

+0

@ cadrell0 Urgh ....你说得对。 –

+0

@ cadrell0 from“where T:class;” – Marco

0

您似乎并不完全了解泛型是如何工作的。我会快速浏览一下,但请阅读MSDN

当你有一个泛型类

public class Foo<T> 
{ 
    public T Bar {get; set;} 
} 

并且你使用这样的事情

Foo<int> intFoo = new Foo<int>(); 
Foo<string> stringFoo = new Foo<string(); 

在编译时,编译器将检测一般类型的两种用法。它将创建每种用法的一种类型。所以你的程序集的类型看起来像这样(不是不完全一样,但是让我们假装让人类可以理解)。

public class FooInt 
{ 
    public int Bar { get; set; } 
} 

public class FooString 
{ 
    public string Bar { get; set; } 
} 

它将与FooIntFoo<string>FooString

现在取代的Foo<int>所有用途,如果我们有一个非通用类与泛型方法

public class Foo 
{ 
    public T GetBar<T>() { ..... } 
} 

你使用它像此

Foo foo = new Foo(); 
int x = foo.GetBar<int>(); 
string s = foo.GetBar<string(); 

编译器将生成

public class Foo 
{ 
    public int GetBarInt() { ..... } 
    public string GetBarString() { ..... } 
} 

它将与GetBarIntGetBar<string>GetBarString

更换GetBar<T>但字段是不是这样的。如果你有一个类,看起来像这样

public class Foo 
{ 
    public T Bar; 
} 

你不能做到这一点

Foo foo = new Foo(); 
foo.Bar<int> = 1; 
foo.Bar<string> = "test"; 

编译器只是不明白这一点。我不是内部专家,但我的猜测是,因为这指向了内存中的某个位置,编译时不能在编译时生成通用用法。

但我想说的是这一点。泛型不是一些神奇的“我不需要指定类型”功能。他们暗示编译时说:“我将多次执行同一个任务,我希望你为我生成代码。”

+0

我完全知道他们是如何工作的,我不知道的是,如果有可能在委托使用的定义中设置一个约束因此是我的问题。回到我的Java时代,大约在2004年,当强大的Sun Java论坛仍在进行时,我对泛型有什么最好的答案,我不记得确切的名字,我相信他的绰号是乔纳森。但是,无论如何感谢:) – Marco