有没有一种方法可以访问嵌套在泛型类中的类而无需指定类型参数?

时间:2020-03-06 16:12:42

标签: c# generics

给出以下几类:

public abstract class User<T> where T : Permission
{
    public ICollection<T> Permissions { get; set; }

    public class Client : User<Permission.Client> { }

    public class Admin : User<Permission.Admin> { }
}

public abstract class Permission
{
    public class Client : Permission { }

    public class Admin : Permission { }
}

您可以创建User<T>.Client的实例,同时将类型参数传递给User<T>,而不是该类本身在实现User<T>中使用的类型。在以下示例中,尽管该类实际上是通过User<T>.Client实现T的,但Permission.Admin是用User<T>作为Permission.Client创建的。

var client = new User<Permission.Admin>.Client();
client.Permissions.Add(new Permission.Client());
client.Permissions.Add(new Permission.Admin()); // cannot convert from 'Permission.Admin' to 'Permission.Client'

至少存在一个构建错误,该错误阻止了向Admin用户添加Client权限。但是,用法可能会引起误解,因为传递给User<T>的类型参数似乎是多余的。


问题:是否有一种方法可以创建User<T>.Client的实例,而不必在T上指定类型参数User(例如{{1} })?

下面是完整示例的dotnetfiddle

1 个答案:

答案 0 :(得分:1)

除了每个人在评论中都提到的有关嵌套类的内容之外,如果要让用户权限同时包含客户端和管理员权限,则需要使用Permission类型的集合

public ICollection<Permission> Permissions { get; set; } = new List<Permission>();

这将解决您的示例,但不会使您的代码更易于遵循。

更新: 为什么您的代码不能再像这样:

public class Program
{
    public static void Main(string[] args)
    {
        var client = new ClientUser();
        client.Permissions.Add(new ClientPermission());
        //This should fail because a client user can't have admin permissions
        client.Permissions.Add(new AdminPermission()); // cannot convert from 'AdminPermission' to 'ClientPermission'
    }


    public abstract class User<T> where T : Permission
    {
        public ICollection<T> Permissions { get; set; } = new List<T>();
    }

    public class ClientUser : User<ClientPermission> { }

    public class AdminUser : User<AdminPermission> { }

    public abstract class Permission
    {
    }

    public class ClientPermission : Permission { }

    public class AdminPermission : Permission { }
}