2016-08-17 45 views
0

考虑以下代码:型专用静态

public class Person 
{ 
    public string Name { get; set; } 
} 

public class Animal 
{ 
    public string Name { get; set; } 
} 

public interface IHandler<T> 
{ 
    T Handle(T eventData); 
} 

public class UpdatePersonHandler : IHandler<Person> 
{ 
    public Person Handle(Person eventData) 
    { 
     var test = eventData.Name; 
     return eventData; 
    } 
} 
public class UpdatePersonHandler2 : IHandler<Person> 
{ 
    public Person Handle(Person eventData) 
    { 
     var test = eventData.Name; 
     return eventData; 
    } 
} 
public class UpdateAnimalHandler : IHandler<Animal> 
{ 
    public Animal Handle(Animal eventData) 
    { 
     var test = eventData.Name; 
     return eventData; 
    } 
} 

public class Bus<T> 
{ 
    public static readonly IList<IHandler<T>> Handlers = new List<IHandler<T>>(); 

    public static void Register(IHandler<T> handler) 
    { 
     if (handler != null) 
      Handlers.Add(handler); 
    } 

    public static void Raise(T eventData) 
    { 
     foreach (var handler in Handlers) 
     { 
      handler.Handle(eventData); 
     } 
    } 
} 

这个测试代码:

[TestMethod] 
public void TestRegister() 
{ 
    Bus<Person>.Register(new UpdatePersonHandler()); 
    Bus<Person>.Register(new UpdatePersonHandler()); 
    Bus<Person>.Register(new UpdatePersonHandler2()); 

    Bus<Animal>.Register(new UpdateAnimalHandler()); 

    Debug.Print(Bus<Person>.Handlers.Count.ToString()); 
    Debug.Print(Bus<Animal>.Handlers.Count.ToString()); 
} 

这个测试的输出:

3 
1 

是什么去这里?

它看起来好像框架正在为通过static注册方法呈现给它的每种类型新建一个总线类。为此,它必须为每个新类型调用Bus<T>的默认构造函数。

但是为什么?这个怎么用?

这是否有任何实际的用途,或者它只是一个有趣的,但令人遐想的C#应该在生产代码中避免的好奇心?

+0

对话[转移到聊天](http://chat.stackoverflow.com/rooms/121216/discussion-between-robert-harvey-and-peter-duniho)。 –

回答

3

是的,传递给静态类Bus<T>的每种不同类型都会导致调用默认构造函数。验证这一个简单的方法是给它一个默认的构造函数:

static Bus(){ Debug.Print("ctor"); } 

使用这将产生输出

ctor 
ctor 
3 
1 

这样做的原因是,泛型类仅用于类模板,这是静态类仍然如此。一旦泛型类型被赋予了Bus类,那么模板就被物化为一个类,这就是构造函数被调用的时候。

该物化类对于同一类的其他通用类型是唯一的。因此,当使用Bus<Person>Bus<Animal>时,这些实际上是单独的类,具有单独的静态成员数据,并且需要单独实例化。

至于使用与普通的打字静态字段的前景,有一个MSDN警告(显然ReSharper的本来就捡起)

CA1000:不要在泛型类型
声明静态成员https://msdn.microsoft.com/en-us/library/ms182139(VS.80).aspx

+1

微软似乎认为这种做法存在的问题是它会扰乱类型推断。该类的多个实例(每个类型一个)似乎并没有打扰他们。 “按设计”,就像它一样。 –

+0

@RobertHarvey:_“这个类的多个实例(每个类型一个)似乎并没有打扰他们” - 完全,也不应该。甚至类型推断的问题都值得商榷。如果在一天结束时,你需要的是一个静态泛型类,或者一个没有任何泛型参数的泛型方法,那就是你需要做的。它确实发生了(一个例子是处理'enum'类型的辅助方法)。请注意,扩展方法可以减轻_some_这种情况的痛苦。 –

+0

不错,我现在明白了 – ShaneKm