60

长话短说,我有一个 C# 函数,它对作为 Object 实例传入的给定类型执行任务。传入类实例时一切正常。但是,当对象被声明为接口时,我真的很想找到具体的类并对该类类型执行操作。

这是一个普遍存在的坏例子(带有不正确的属性大小写等):

public interface IA
{
    int a { get; set; }
}
public class B : IA
{
    public int a { get; set; }
    public int b { get; set; }
}
public class C : IA
{
    public int a { get; set; }
    public int c { get; set; }
}

// snip

IA myBObject = new B();
PerformAction(myBObject);

IA myCObject = new C();
PerformAction(myCObject);

// snip

void PerformAction(object myObject)
{
    Type objectType = myObject.GetType();   // Here is where I get typeof(IA)
    if ( objectType.IsInterface )
    {
        // I want to determine the actual Concrete Type, i.e. either B or C
        // objectType = DetermineConcreteType(objectType);
    }
    // snip - other actions on objectType
}

我希望 PerformAction 中的代码对其参数使用反射,并看到它不仅是 IA 的实例,而且是 B 的实例,并通过 GetProperties() 查看属性“b”。如果我使用 .GetType() 我会得到 IA 的类型 - 这不是我想要的。

PerformAction 如何确定 IA 实例的底层具体类型?

有些人可能会建议使用 Abstract 类,但这只是我的坏例子的限制。该变量最初将被声明为接口实例。

4

5 回答 5

89
Type objectType = myObject.GetType();

根据您的示例,仍应为您提供具体类型。

于 2009-07-21T15:27:00.303 回答
5

我必须同意糟糕的设计。如果你有一个接口,那应该是因为你需要使用一些通用的功能,而不关心具体的实现是什么。以您为例,听起来 PerformAction 方法实际上应该是接口的一部分:

public interface IA
{
    int a { get; set; }
    void PerformAction();
}

public class B: IA
{
    public int a { get; set; }
    public int b { get; set; }

    public void PerformAction()
    {
        // perform action specific to B
    }
}

public class C : IA
{
    public int a { get; set; }
    public int c { get; set; }

    public void PerformAction()
    {
        // perform action specific to C
    }
}

void PerformActionOn(IA instance)
{
    if (instance == null) throw new ArgumentNullException("instance");

    instance.PerformAction();

    // Do some other common work...
}


B b = new B();
C c = new C();

PerformActionOn(b);
PerformActionOn(c);
于 2009-07-22T01:29:42.940 回答
5

你在做什么真的是床设计,但你不必使用反射你可以像这样检查它

void PerformAction(object myObject)
{
    B objectType = myObject as B;   // Here is where I get typeof(IA)
    if ( objectType != null )
    {
        //use objectType.b
    }
    else
    {
       //Same with A 
    }
    // snip - other actions on objectType
}
于 2009-07-21T15:26:20.260 回答
3

您永远不能拥有接口的实例。因此,确定您是在处理接口还是具体类型是不可能的,因为您将始终处理具体类型。所以我不确定你的问题是否有意义。你到底想做什么,为什么?

于 2009-07-21T15:25:04.457 回答
2

也许您正在寻找is 运算符

void PerformAction(object myObject)
{
    if (myObject is B)
    {
        B myBObject = myObject as B;
        myBObject.b = 1;
    }

    if (myObject is C)
    {
        C myCObject = myObject as C;
        myCObject.c = 1;
    }

    // snip - other actions on objectType
}
于 2009-07-22T01:22:15.023 回答