C# 创建一个类来存储使用不同接口的类

C# 创建一个类来存储使用不同接口的类,c#,class,C#,Class,我正在从事一个C#项目,该项目需要存储有关用户的信息。这些信息从各自的库中检索,这些库有自己的实现和接口。目前,用户可以从Twitch或Discord连接,因此他们将被表示为TwitchUser或DiscordUser对象。但是,我想编写一个类User,它将包含两个类中的一个,这将使我更容易在代码中引用它们 以下是TwitchUser和DiscordUser的外观示例: public class TwitchUser : IChatUser { public Tw

我正在从事一个C#项目,该项目需要存储有关用户的信息。这些信息从各自的库中检索,这些库有自己的实现和接口。目前,用户可以从Twitch或Discord连接,因此他们将被表示为TwitchUser或DiscordUser对象。但是,我想编写一个类User,它将包含两个类中的一个,这将使我更容易在代码中引用它们

以下是TwitchUser和DiscordUser的外观示例:

    public class TwitchUser : IChatUser
    {
        public TwitchUser();

        public string Id { get; }
        public string UserName { get; }
        public string DisplayName { get; }
        public string Color { get; }
//and so on...
    }
公共类DiscordUser:SnowflakeObject,IEquatable
{
公共虚拟字符串电子邮件{get;internal set;}
公共虚拟字符串用户名{get;internal set;}
公共布尔等于(不协调用户e);
//等等。。。
}
我想我可以创建一个接受泛型类型的类,但在我的实现中,我必须传递两个类,这意味着其中一个类将为null。我觉得这不对

    public class User<T,D>
    {
        public TwitchUser VarA { get; set; }
        public DiscordUser VarB { get; set; }
    }
公共类用户
{
公共TwitchUser VarA{get;set;}
公共DiscordUser VarB{get;set;}
}
组合两个具有不同实现且没有共同接口的类的正确方法是什么? 然后,我还会在User类中编写代码,以返回用户ID等

更新 例如,当我请求一个用户ID时,我将在user内部执行一个检查,检查我是否存储了TwitchUser或DiscordUser,并根据结果返回一个表示该平台上用户ID的属性

更新2 用户只能由两个类中的一个表示。例如,如果他们使用Discord作为登录平台,那么他们将只有一个DiscordUser对象与他们关联。同样适用于Twitch平台和使用TwitchUser对象的it。它们之所以不同,是因为这些实现是由不同的人使用两个不同的库编写的,这就是为什么它们不使用相同的接口,也不从一个公共类继承。所以我想做的是追溯性地在这里添加某种继承。这样,当我想在代码中引用用户时,我不需要为一个函数编写两个重载(其中一个使用TwitchUser,另一个使用DiscordUser)。我只想能够引用用户,让该类为我做出决定

“组合两个具有不同实现且没有共同接口的类的正确方法是什么?”

实现这一点的一种方法可能是创建一个包含您关心的所有属性的类,然后创建静态方法,该方法基于
TwitchUser
DiscordUser
的属性返回该类的实例:

public class User
{
    // Add just the properties you care about
    public string Id { get; private set; }
    public string UserName { get; private set; }
    public string DisplayName { get; private set; }
    public string Color { get; private set; }
    public string Email { get; private set; }

    // Make the default constructor private so instances of this
    // class can only be created from one of our static methods
    private User() { }

    public static User FromTwitch(TwitchUser twitchUser)
    {
        return new User
        {
            Id = twitchUser.Id,
            Color = twitchUser.Color,
            DisplayName = twitchUser.DisplayName,
            UserName = twitchUser.UserName
        };
    }

    public static User FromDiscord(DiscordUser discordUser)
    {
        return new User
        {
            Email = discordUser.Email,
            UserName = discordUser.Username
        };
    }
}
我提到的这两个类别无法修改[…]我希望能够访问DiscordUser和TwitchUser中存储的所有必要属性

这听起来很适合适配器模式。将接口定义为公共分母:

public interface IUser
{
    string Id { get; }
    string Username { get; }
}
请注意,此接口只能包含两个对象共享的属性,否则您将需要到处进行空检查

然后为要包装的每种类型创建适配器:

public class TwitchUserAdapter : IUser
{
    private readonly TwitchUser _user;
    
    public TwitchUserAdapter(TwitchUser user)
    {
        _user = user;
    }
    
    public string Id => _user.Id;
    public string Username => _user.UserName;
}

public class DiscordUserAdapter : IUser
{
    private readonly DiscordUser _user;
    
    public TwitchUserAdapter(DiscordUser user)
    {
        _user = user;
    }
    
    public string Id => _user.Id;
    public string Username => _user.Username;
}
现在,您可以对两者进行相同的处理:

var users = new List<IUser>();

users.Add(new TwitchUserAdapter(new TwitchUser { Id = "Tfoo", UserName = "Tbar" }));
users.Add(new DiscordUserAdapter(new DiscordUser { Id = "Dfoo", Username = "Dbar" }));

foreach (var user in users)
{
    Console.WriteLine($"Id: {user.Id}, Name: {user.Username}");
}
var users=newlist();
Add(新TwitchUserAdapter(新TwitchUser{Id=“Tfoo”,UserName=“Tbar”});
Add(newdiscorduseradapter(newdiscorduser{Id=“Dfoo”,Username=“Dbar”}));
foreach(用户中的var用户)
{
WriteLine($“Id:{user.Id},Name:{user.Username}”);
}

这一切都取决于您到底想做什么,您已经花了大约半句话来解释:“返回用户ID等”。这是什么意思?你打算如何处理这些数据?如果一端的电子邮件地址是标识符,另一端的用户名是唯一的呢?或者,如果一个服务有自己的标识符,比如GUID,该怎么办?至于您的实现,您甚至不使用泛型类型参数。T和D与TwittHuffor和DeCordDuffor没有任何关系。您可以考虑编写自己的接口,如“代码> String USERID {GET;},并让您显示的类实现该接口:<代码>公共字符串用户ID {GET {返回用户名;}}/<代码>例如,我添加了一个简短的更新来解释用户ID用例。当然,如果我想返回其他属性,我会以类似的方式再次执行检查,并从任何一个类返回相应的属性。显然,如果这两个类都不包含公共属性(例如,TwitchUser有IssuSubscriber,DiscordUser没有),那么我就不必费心实现一个函数来返回该属性。我不清楚何时以及为什么会有这两个类中的一个或两个的实例,你对哪些房产感兴趣,什么时候,为什么。如果用户同时拥有Twitch和Discord帐户怎么办?您确实需要提供更多的上下文。我添加了另一个更新,希望能够更好地解释我的情况。为什么不引入一个具有这些属性的接口
IUser
,并让这两个类实现该接口?如果他能够控制这些类,这也会起作用。我不完全理解他的情况
var users = new List<IUser>();

users.Add(new TwitchUserAdapter(new TwitchUser { Id = "Tfoo", UserName = "Tbar" }));
users.Add(new DiscordUserAdapter(new DiscordUser { Id = "Dfoo", Username = "Dbar" }));

foreach (var user in users)
{
    Console.WriteLine($"Id: {user.Id}, Name: {user.Username}");
}