泛型类中特定于类型的静态

时间:2016-08-17 23:05:17

标签: c# generics static static-methods

考虑以下代码:

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 Register方法呈现给它的每种类型新建一个Bus类。为此,它必须为Bus<T>调用每个新类型的默认构造函数。

但为什么呢?这是如何工作的?

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

1 个答案:

答案 0 :(得分: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

相关问题