我可以使用另一个接口实现从接口转换为具体类型 [英] Can I cast from an interface to a concrete type with another interface implementation

查看:630
本文介绍了我可以使用另一个接口实现从接口转换为具体类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我应该首先说我非常喜欢接口,所以这可能是一个非常愚蠢的问题。如果我的标题不清楚也要道歉 - 与我的想法相符!



我理解接口背后的原理,我想在这里使用它们来支持单元测试并且还通过DI框架在可怕的混乱和不可测试的遗留代码中进行解耦。



我有一个名为IDatHandler的接口。它有一个名为Items的List<>属性。具体实现应返回具体类型的IDatContainer。当然有一些方法,但我把它们遗漏了

 公共接口IDatHandler 
{
.. ..

List< IDatContainer>物品
{
get;组;
}

}

这是一个具体的实现:

 公共类ADEColorHandler:IDatHandler 
{
....

public列表与LT; ADEColor>物品
{
get;组;

}

}
}

ADEColor实现了IDatContainer。具体实现失败,除非我用 IDatContainer 替换 ADEColor



有没有办法让项目返回为 ADEColor 类型的列表,还是我只是违反了规则?



<我应该说这个应用程序目前正在使用NET 3.5



========= >>>答案 - 感谢Charleh!



IDatHandler接口

 公共接口IDatHandler< T>其中T:IDatContainer 
{
....

List< IDatContainer>物品
{
get;组;
}

}

具体类:

 公共类ADEColorHandler:IDatHandler< ADEColor> 
{
....

public List< ADEColor>物品
{
get;组;

}

}
}

我的单位测试ADEColorHandler断言此列表并传递。

解决方案

你可以走这条路:

 公共接口IDatHandler 
{
//任何常见接口东西
}

公共接口IDatHandler< T> :IDatHandler
其中T:IDatContainer
{
//任何泛型
List< T>项目;
}

公共类ADEColorHandler:IDatHandler< ADEColor>
{
....

public List< ADEColor>物品
{
get;组;

}

}

这意味着你需要在另一端进行一些转换,因为如果你只是传递 IDatHandler 实例,你需要知道泛型类型才能查询物品



你想要达到什么目的?这可能有助于确定您可以使用的内容...



或者您可以在原始界面实现中使用IEnumerable - 您是否需要在设计时了解集合的具体类型时间或者你可以逃脱投射?



编辑:添加上面的约束



只是想让我的围绕这个,因为使用上面的界面将在一定程度上工作,但我的假设是你想循环通过这些来处理它们等 - 我想知道这是否有效(需要检查)

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

然后你可以枚举列表...只是检查一下是否有效。



编辑:nope,由于泛型类型在运行时实际上不同,因此无效。我会乱七八糟 - 我喜欢尝试找出你能做什么,不能用泛型做什么!



编辑:



好,所以最好的可能是:

 公共接口IDatHandler< T> :IDatHandler 
其中T:IDatContainer
{
List< T>物品{get;组; }
}

公共类ADEColorHandler:IDatHandler< IDatContainer>
{
公开列表< IDatContainer>物品
{
get;
设定;

}
}

这意味着你可以:

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

然后你可以枚举并获得 Items 来自每个 IDatHandler 并查询每个 IDatContainer 。当然,您对具体类型隐藏,但我假设您在容器上有一个接口,以尝试抽象这些实现细节。这应该没问题


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.

I have an inteface called IDatHandler. It has a List<> property called Items. The concrete implementations should return a concrete type of 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. The concrete implementation fails unless I replace ADEColor with IDatContainer.

Is there a way to get Items returned as a list of type ADEColor or am I just breaking the rules?

I should have said that this app is currently using NET 3.5

=========>>> The Answer - thanks Charleh!

The IDatHandler Interface

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.

解决方案

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

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?

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. 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. 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

这篇关于我可以使用另一个接口实现从接口转换为具体类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆