简体   繁体   English

我可以使用另一个接口实现从接口转换为具体类型

[英]Can I cast from an interface to a concrete type with another interface implementation

I should start by saying that I am very much a noobie with interfaces so this might be a really dumb question. 我应该首先说我非常喜欢接口,所以这可能是一个非常愚蠢的问题。 Also apologies if my Title is unclear - matches the state of my mind! 如果我的标题不清楚也要道歉 - 符合我的想法!

I do understand the principles behind interfaces and I am want to use them here both to support unit testing and also decoupling via a DI Framework in what is horribly messy and un-testable legacy code. 我确实理解接口背后的原理,我想在这里使用它们来支持单元测试,并通过DI Framework解耦,这是一个非常混乱和无法测试的遗留代码。

I have an inteface called IDatHandler. 我有一个名为IDatHandler的接口。 It has a List<> property called Items. 它有一个名为Items的List <>属性。 The concrete implementations should return a concrete type of IDatContainer. 具体实现应返回具体类型的IDatContainer。 There are some methods of course but I have left them out 当然有一些方法,但我把它们排除在外

public interface IDatHandler
{
    ....

   List<IDatContainer> Items
    {
        get; set;
    }

}

This is a concrete implementation: 这是一个具体的实现:

public class ADEColorHandler : IDatHandler
    {
      ....

        public List<ADEColor> Items
        {
            get; set;

        }

    }
}

ADEColor implements IDatContainer. ADEColor实现了IDatContainer。 The concrete implementation fails unless I replace ADEColor with IDatContainer . 除非我替换的具体实施失败ADEColorIDatContainer

Is there a way to get Items returned as a list of type ADEColor or am I just breaking the rules? 有没有办法让ADEColor作为ADEColor类型的列表返回,或者我只是违反规则?

I should have said that this app is currently using NET 3.5 我应该说这个应用程序目前正在使用NET 3.5

=========>>> The Answer - thanks Charleh! ========= >>>答案 - 感谢Charleh!

The IDatHandler Interface IDatHandler接口

public interface IDatHandler<T> where T : IDatContainer
{
    ....

   List<IDatContainer> Items
    {
        get; set;
    }

}

The concrete Class: 具体课程:

public class ADEColorHandler : IDatHandler<ADEColor>
        {
          ....

            public List<ADEColor> Items
            {
                get; set;

            }

        }
    }

My units tests on ADEColorHandler Assert against this list and pass. 我的单元测试ADEColorHandler断言此列表并通过。

You could go this route: 你可以走这条路:

public interface IDatHandler
{
    // Any common interface stuff
}

public interface IDatHandler<T> : IDatHandler
    where T : IDatContainer
{
    // Any generics
    List<T> Items;
}

public class ADEColorHandler : IDatHandler<ADEColor>
{
  ....

    public List<ADEColor> Items
    {
        get; set;

    }

}

This does mean you need to do some casting at the other end though since if you just pass around IDatHandler instances, you need to know the generic type before you can query Items 这确实意味着你需要在另一端进行一些转换,因为如果你只是传递IDatHandler实例,你需要知道泛型类型才能查询Items

What are you trying to achieve? 你想要实现什么目标? That might help determine what you can use... 这可能有助于确定你可以使用什么......

Alternatively you could use IEnumerable in your original interface implementation - do you need to know the concrete type of the collection at design time or can you get away with casting? 或者,您可以在原始界面实现中使用IEnumerable - 您是否需要在设计时知道集合的具体类型,或者您可以通过投射来逃避?

Edit: added the constraint above 编辑:添加上面的约束

Just trying to get my head round this because using the above interface will work to a certain degree but my assumption is that you want to loop through these to process them etc - I'm wondering if this would work (need to check) 只是试图让我的头脑,因为使用上面的界面将在一定程度上工作,但我的假设是你想循环通过这些来处理它们等 - 我想知道这是否有用(需要检查)

List<IDatHandler<IDatContainer>> someList = new List<IDatHandler<IDatContainer>>();
someList.Add((IDatHandler<IDatContainer>)new ADEColorHandler());           

Then you could enumerate the list... going to just check to see if this works. 然后你可以枚举列表......只是检查一下是否有效。

Edit: nope, didn't work since the generic type is actually different at runtime. 编辑:nope,没有工作,因为泛型类型在运行时实际上是不同的。 I'll have a mess around - I enjoy trying to work out what you can and can't do with generics! 我会乱七八糟 - 我喜欢尝试找出你能做什么,不能用泛型做什么!

Edit: 编辑:

Ok so the best one is probably: 好的,最好的可能是:

    public interface IDatHandler<T> : IDatHandler
        where T : IDatContainer
    {
        List<T> Items { get; set; }
    }

    public class ADEColorHandler : IDatHandler<IDatContainer>
    {
        public List<IDatContainer> Items
        {
            get;
            set;

        }
    }

Which means you can do: 这意味着你可以做到:

var items = new List<IDatHandler<IDatContainer>>();
items.Add(new ADEColorHandler());      

then you can enumerate and get Items from each IDatHandler and query each IDatContainer . 然后,您可以枚举并从每个IDatHandler获取Items并查询每个IDatContainer Of course you are hidden from the concrete types but I assume you have an interface on the containers to try and abstract those implementation details. 当然,您从具体类型中隐藏,但我假设您在容器上有一个接口来尝试抽象这些实现细节。 This should be fine 这应该没问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM