Uses for static generic classes?

2020-02-02 11:51发布

What are the key uses of a Static Generic Class in C#? When should they be used? What examples best illustrate their usage?

e.g.

public static class Example<T>
{
   public static ...
}

Since you can't define extension methods in them they appear to be somewhat limited in their utility. Web references on the topic are scarce so clearly there aren't a lot of people using them. Here's a couple:-

http://ayende.com/Blog/archive/2005/10/05/StaticGenericClass.aspx

Static Generic Class as Dictionary


Summary of Answers Given

The key issues appear to be "What's the difference between a static generic class with static methods and a non-generic static class with static generic members?"

The decision as to which to use appears to revolve around "Does the class need to store type-specific state internally?"

If there is no need for type-specific internal storage then a static non-generic class with generic static methods appears to be preferable because the calling syntax is nicer and you can define extension methods within it.

9条回答
霸刀☆藐视天下
2楼-- · 2020-02-02 12:33

I use these to mock a DbSet when testing against classes that use EntityFramework Async methods.

public static class DatabaseMockSetProvider<TEntity> where TEntity: class
{
    public static DbSet<TEntity> CreateMockedDbSet(IQueryable<TEntity> mockData)
    {
        var mockSet = Mock.Create<DbSet<TEntity>>();
        Mock.Arrange(() => ((IDbAsyncEnumerable<TEntity>)mockSet).GetAsyncEnumerator())
            .Returns(new TestDbAsyncEnumerator<TEntity>(mockData.GetEnumerator()));
        Mock.Arrange(() => ((IQueryable<TEntity>)mockSet).Provider)
            .Returns(new TestDbAsyncQueryProvider<TEntity>(mockData.Provider));
        Mock.Arrange(() => ((IQueryable<TEntity>)mockSet).Expression).Returns(mockData.Expression);
        Mock.Arrange(() => ((IQueryable<TEntity>)mockSet).ElementType).Returns(mockData.ElementType);
        Mock.Arrange(() => ((IQueryable<TEntity>)mockSet).GetEnumerator()).Returns(mockData.GetEnumerator());

        return mockSet;
    }
}

And use them like so in my unit tests - saves a lot of time and can use them for any entity types:

var mockSet = DatabaseMockSetProvider<RecipeEntity>.CreateMockedDbSet(recipes);
        Mock.Arrange(() => context.RecipeEntities).ReturnsCollection(mockSet);
查看更多
小情绪 Triste *
3楼-- · 2020-02-02 12:33

You're right: they're not much use. Perhaps there are some rare cases that are exceptions, though. For example, what if the class was a type-specific repository, as in Justin's example, but kept a static collection as a cache? In general, if it contains state, not just methods, there may be a point to this.

查看更多
劫难
4楼-- · 2020-02-02 12:35

A static generic class is exactly as useful as any given static class. The difference is that you don't have to use copy-and-paste to create a version of the static class for each type you want it to work on. You make the class generic, and you can "generate" one version for each set of type parameters.

查看更多
登录 后发表回答