C# - 从派生类调用基类方法时的类型转换问题

时间:2014-07-03 19:44:43

标签: c# inheritance casting type-conversion

我需要从Active Directory检索扩展属性 在ComputerPrincipal类中有一个私有方法。一世 明白我只能通过派生来访问私有方法 因为我从基础派生了一个班级ComputerPrincipalEx 类。然后,我在派生类中创建(定义?)方法 它调用基类中的私有方法。这部分似乎没问题。

当我尝试使用基础的(公共)方法时出现问题 class,用于为具有派生类型的变量赋值 类。这是代码,然后我会尝试解释更多:

派生类:

public class ComputerPrincipalEx : ComputerPrincipal
{
    public ComputerPrincipalEx(PrincipalContext context) : base(context) { }

    public ComputerPrincipalEx(PrincipalContext context, string samAccountName, string password, bool enabled) : base(context, samAccountName, password, enabled) { }

    public string ExtensionGet(string extendedattribute)
    {
        return (string) base.ExtensionGet(extendedattribute)[0];
    }

}

问题代码,它本身就是我创建的另一个类的方法:

public string GetExtendedAttribute(string attributeName)
    {
        PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
        ComputerPrincipalEx cp = new ComputerPrincipalEx(ctx);
        cp = ComputerPrincipalEx.FindByIdentity(ctx, Name);
        return cp.ExtensionGet(attributeName);
    }

ExtensionGet是我需要的基类的私有方法 暴露,我认为我有这个正确,因为一旦我创建了一个 ComputerPrincipalEx类型的对象,我可以访问ExtensionGet,其中 否则无法访问。

问题是此行中的类型转换:     cp = ComputerPrincipalEx.FindByIdentity(ctx,Name);

cp定义为ComputerPrincipalEx; ComputerPrincipalEx.FindByIdentity引用了基础 ComputerPrincipal.FindByIdentity方法,并返回一个 ComputerPrincipal。编译器关于隐式转换 类型之间。将ComputerPrincipal投射到ComputerPrincipalEx 满足编译器,但应用程序在运行时崩溃,因为它不能 执行转换。

现在,我完全理解所有这些,但我假设有 从某种方法调用基类中的方法并返回有效 数据到派生类的对象'类型,这就是我的意思 希望了解如何做。

3 个答案:

答案 0 :(得分:1)

我能够根据找到herehere的信息来解决这个问题。

在派生的ComputerPrincipalEx类中,我需要隐藏基类“FindByIdentity方法并重新定义它以调用FindByIdentityWithType。这让我将返回类型转换为ComputerPrincipalEx,从而访问ExtensionGet方法。 (希望我能正确解释这一点;这对我来说仍然是一个新事物。)

为了使其工作,还需要添加以下行。否则,编译器会抛出ComputerPrincipalEx不是要搜索的有效对象类型的错误。

[DirectoryObjectClass("computer")]
[DirectoryRdnPrefix("CN")]

以下是ComputerPrincipalEx类的相关摘录:(是的,我知道try / catch块需要一些工作。)

[DirectoryObjectClass("computer")]
[DirectoryRdnPrefix("CN")]

public class ComputerPrincipalEx : ComputerPrincipal
{
    public ComputerPrincipalEx(PrincipalContext context) : base(context) { }

    public ComputerPrincipalEx(PrincipalContext context, string samAccountName, string password, bool enabled) : base(context, samAccountName, password, enabled) { }

    new public string ExtensionGet(string extendedattribute)
    {
        try
        {
            if (base.ExtensionGet(extendedattribute).Length != 1)
            {
                return null;
            }
            else
            {
                return (string)base.ExtensionGet(extendedattribute)[0];
            }
        }
        catch (Exception ex)
        {
            // This should be broken down to individual exceptions
            string message = string.Format("Exception occurred while retrieving extended attribute {0}. \r\nThe following error occurred:\r\n {1}", extendedattribute, ex);
            MessageBox.Show(message);
            Application.Exit();
            return null;
        }
    }

    public static new ComputerPrincipalEx FindByIdentity(PrincipalContext ctx, string identityValue)
    {
        return (ComputerPrincipalEx)FindByIdentityWithType(ctx, typeof(ComputerPrincipalEx), identityValue);
    }
}

修订后的GetExtendedAttribute电话:

    public string GetExtendedAttribute(string attributeName)
    {
        PrincipalContext ctx = new PrincipalContext(ContextType.Domain); 
        var cp = ComputerPrincipalEx.FindByIdentity(ctx, Name); 
        return cp.ExtensionGet(attributeName);

    }

谢谢大家的帮助。希望这可以帮助遇到同样问题的其他人。

答案 1 :(得分:0)

更改为:

public string GetExtendedAttribute(string attributeName)
    {
        PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
        var cp = ComputerPrincipalEx.FindByIdentity(ctx, Name);
        return cp.ExtensionGet(attributeName);
    }

答案 2 :(得分:0)

在我的印象中,您需要ComputerPrincipalEx中的构造函数(或静态方法),它从基类的实例创建它。