C# 使用接口定义的类';s其他方法并保持智能感知

C# 使用接口定义的类';s其他方法并保持智能感知,c#,.net,dynamic,interface,C#,.net,Dynamic,Interface,问题涉及以下方面: IUser user = new Guest(); var stuff = user.guestname; //no definition for guestname 这里我得到一个错误,IUser不包含任何访客名称(当然)。 我需要一个方法或属性,该方法或属性提供了我想要的东西——获取实例化类的成员,即使它被定义为接口 事实上,我有,使用动力学: IUser应定义一个实例道具,如下所示: dynamic Instance { get; } 并由来宾实施: public

问题涉及以下方面:

IUser user = new Guest();
var stuff = user.guestname; //no definition for guestname
这里我得到一个错误,
IUser
不包含任何访客名称(当然)。 我需要一个方法或属性,该方法或属性提供了我想要的东西——获取实例化类的成员,即使它被定义为接口

事实上,我有,使用动力学:

IUser
应定义一个
实例
道具,如下所示:

dynamic Instance { get; }
并由
来宾实施

public dynamic Instance
{
    get
    {
        return this;
    }
}
小菜一碟,我现在可以得到实例化的类型了,它可以工作了

IUser user = new Guest();
var stuff = user.Instance.guestname; //runs fine.
但是这个问题

…当然是因为动态类型,我没有智能感知

我想到:

  • 在接口内部定义一个调用,并在实现该接口的所有类中实现一个
    getter
    ,并返回它们自己的值,但是接口不知道将实现它的类,因此它只能返回该
    IUser
    ,因此毫无用处
  • 尝试使用泛型,但我不得不这样称呼它:

    user.Get().SomeMethod()
    ; 因此,它基本上不超过使用
    (用户作为管理员)
    ,因此没有帮助

  • 我现在想的是,我应该动态地创建getter方法,比如在程序初始化时,查找实现这个
    IUser
    的所有类,并在其中添加适当的getter。我不知道这是否可行,或者如果可行,那么怎么做
那么问题又来了


这就是我使用
dynamic
关键字所做的事情,但实际上保留了Visual Studio的intellisense功能吗

有多种方法,最简单的方法是将对象强制转换为所需的类型,例如:

IUser user = new Guest();

...

var guest = user as Guest;
var guestName = guest.guestname;
public interface IUser
{
    string GetName();
}

public class Guest : IUser
{
    private readonly string _guestName;

    public Guest(string guestName)
    {
        _guestName = guestName;
    }

    public string GetName()
    {
        return _guestName;
    }
}

public class Admin : IUser
{
    private readonly string _adminName;

    public Guest(string adminName)
    {
        _adminName = adminName;
    }

    public string GetName()
    {
        return _adminName;
    }
}
然而,这几乎总是一种代码气味。您真正应该做的是定义接口上的属性和方法,并让子对象实现它们。例如:

IUser user = new Guest();

...

var guest = user as Guest;
var guestName = guest.guestname;
public interface IUser
{
    string GetName();
}

public class Guest : IUser
{
    private readonly string _guestName;

    public Guest(string guestName)
    {
        _guestName = guestName;
    }

    public string GetName()
    {
        return _guestName;
    }
}

public class Admin : IUser
{
    private readonly string _adminName;

    public Guest(string adminName)
    {
        _adminName = adminName;
    }

    public string GetName()
    {
        return _adminName;
    }
}

有多种方法,最简单的方法是将对象强制转换为所需的类型,例如:

IUser user = new Guest();

...

var guest = user as Guest;
var guestName = guest.guestname;
public interface IUser
{
    string GetName();
}

public class Guest : IUser
{
    private readonly string _guestName;

    public Guest(string guestName)
    {
        _guestName = guestName;
    }

    public string GetName()
    {
        return _guestName;
    }
}

public class Admin : IUser
{
    private readonly string _adminName;

    public Guest(string adminName)
    {
        _adminName = adminName;
    }

    public string GetName()
    {
        return _adminName;
    }
}
然而,这几乎总是一种代码气味。您真正应该做的是定义接口上的属性和方法,并让子对象实现它们。例如:

IUser user = new Guest();

...

var guest = user as Guest;
var guestName = guest.guestname;
public interface IUser
{
    string GetName();
}

public class Guest : IUser
{
    private readonly string _guestName;

    public Guest(string guestName)
    {
        _guestName = guestName;
    }

    public string GetName()
    {
        return _guestName;
    }
}

public class Admin : IUser
{
    private readonly string _adminName;

    public Guest(string adminName)
    {
        _adminName = adminName;
    }

    public string GetName()
    {
        return _adminName;
    }
}

因此,您正在尝试使用OOP功能,同时您正在使用与OOP完全相反的动力学!只要它能工作就无所谓了:DSo你想写糟糕的代码吗?当我失去intellisense或者当我不断检查IUser是否是我给定的类时,我更容易出错,如果是,就这样使用它。你在这里所做的就是我们所说的“代码气味”,违反了坚实的原则。如果您有类型为
IUser
的对象,则应始终将其视为此类对象。如果您发现需要使用其他属性,那么您应该重新考虑您的整体结构。因此,您正在尝试使用OOP功能,同时您正在使用与OOP完全相反的动力学!只要它能工作就无所谓了:DSo你想写糟糕的代码吗?当我失去intellisense或者当我不断检查IUser是否是我给定的类时,我更容易出错,如果是,就这样使用它。你在这里所做的就是我们所说的“代码气味”,违反了坚实的原则。如果您有类型为
IUser
的对象,则应始终将其视为此类对象。如果您发现需要使用其他属性,那么您应该重新考虑您的整体结构。因此,基本上重新设计更可行。谢谢你指出错误!所以基本上重新设计是更可行的。谢谢你指出错误!