【问题标题】:Cannot access public methods through dll无法通过 dll 访问公共方法
【发布时间】:2015-11-16 08:37:30
【问题描述】:

我有一个函数QMain(),它的返回类型是object

public class QMain
{
    public object objQ(string str)
    {
        if (str.ToUpper() == "A")
        {
            clsA objA = new clsA();
            return objA;
        }
        else if (str.ToUpper() == "B")
        {
            clsB objB = new clsB();
            return objB;
        }
        else
            return "";
    }

}

以下是clsA

public class clsA 
{
   public string strMessage { get; private set; }
   public static string staticField;
   public bool cantAccessThisFn(string str)
   {...}
}

以上两个类都在同一个项目中,这是一个类库。我创建了另一个控制台应用程序,其中包含了上述项目的dll。现在,我正在做:

QMain obj=new QMain();
object A=obj.objQ("A");

我可以得到strMessagestaticField,但不能得到cantAccessThisFn。如果我直接创建clsA 的对象,我可以得到cantAccessThisFn。有什么方法可以从 obj(QMain 类的对象)访问这个函数? 我收到以下错误:

'object' 不包含 'cantAccessThisFn' 的定义,并且没有扩展方法 'cantAccessThisFn' 接受第一个参数 可以找到类型“对象”(您是否缺少 using 指令或 汇编参考?)

【问题讨论】:

  • 我不是你“获得”这些领域的方式。类型 object 没有这样的字段,这就是您正在使用的,除非您转换为您的类型之一。
  • 您想从clsA.cantAccessThisFn 访问cantAccessThisFn?还是来自一个实例?

标签: c#


【解决方案1】:

问题是你的objQ 方法返回一个object。您还没有在object 上定义任何(扩展)方法,所以cantAccessThisFn 肯定无法访问。

你应该做的是:用你想在两个类之间共享的所有方法创建一个接口,不要返回object,而是返回IYourInterfaceName。然后你就可以访问接口上定义的那些方法和属性了。

类似这样的:

public class clsA : IYourInterface
{
    ...
}

public interface IYourInterface
{
    string strMessage { get; }
    bool cantAccessThisFn(string str);
}

那么你的方法应该是这样的:

public IYourInterface objQ(string str)
{ ... }

你的任务是这样的:

IYourInterface a = obj.objQ("A");

现在可以调用了:

a.cantAccessThisFn("z");

【讨论】:

  • 嗨帕特里克,问题是 ClsA 和 ClsB 有不同的功能集。还有其他出路吗?
  • 是的,但对我来说这感觉像是一个设计缺陷。正如 Seabizkit 回答的那样,您可以检查字段的类型,但我不建议这样做。你为什么要设计现在的代码?
  • 有各种类,每个类都用一个字符串指定,我们想在其他项目中通过该字符串访问这些类的函数。您还有其他有效的方法吗?
  • @pika,从技术上讲,我认为您应该提出一个新问题。我的回答确实解释了如何使用您当前的代码来做到这一点,我的回答并未解决您的设计问题,但确实解决了当前代码的问题。我相信你需要问一个新问题......按照我如何设计 xyz 以在给定 x 或 y 的情况下实现 xyz。
【解决方案2】:

这是为了帮助你理解!并且不是推荐的解决方案。

Marked Patricks 回答,因为这是更正确的方式... 但要实现你所拥有的,你可以做类似的事情。

我还为类、属性和局部变量应用了标准命名骆驼案例。

这也允许 ClsA 和 ClsB 具有完全不同的方法/属性名称。 再次重申,我并不是建议这样做,而是为了帮助了解它发生了什么。

public class Program
{
    static void Main()
    {

        QMain obj = new QMain();
        object a = obj.objQ("A");

        //FYI the below commended out is not possible...
        //ClsA.staticField is but that is not the instance you created.
        //------------
        //a.staticField //<--- not possible
        //------------

        var someA = a as ClsA; //<--- attempts to cast it as ClsA
        var someB = a as ClsB; //<--- attempts to cast it as ClsB
        if (someA != null) //check if the cast was successful
        {
            var var1 = someA.StrMessage;
        }
        else if (someB != null)
        {
            //...
        }
    }
}

public class QMain
{
    public object objQ(string str)
    {
        if (str.ToUpper() == "A")
        {
            ClsA objA = new ClsA();
            return objA;
        }
        else if (str.ToUpper() == "B")
        {
            ClsB objB = new ClsB();
            return objB;
        }
        else
            return "";
    }

}

public class ClsA
{
    public string StrMessage { get; private set; }
    public static string StaticField;
    public bool CantAccessThisFn(string str)
    {
        return true;
    }
}

public class ClsB
{
    public string StrMessageMyC { get; private set; }
    public static string StaticFieldMyC;
    public bool CantAccessThisFnMyC(string str)
    {
        return true;
    }
}

【讨论】:

  • 嗨 Seabizkit,我不想使用 ClsA/ ClsB。
  • 嗨?它被标记为答案....现在不是?困惑...你能告诉我你的意思吗?谢谢
猜你喜欢
  • 2014-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多