English 中文(简体)
采用多种类别/接口进行过滤
原标题:List filtering using multiple classes/interfaces

基本 我有一个物体清单,每个物体可使用一套不同的界面:

List<BaseObject> objects;

class BaseObject
{
  public void DoStuff();
}

interface IX
{
  void DoX();
}

interface IY
{
  void DoY();
}

interface IZ
{
  void DoZ();
}

我也想写这样的文字:

foreach(var obj in objects.OfType<BaseObject and IX>)
{
  obj.DoStuff();
  obj.DoX();
}

(E.g. i. 对基地物体和九类物体进行特定算法,而不必在那里进行分类)

Is it possible to do in C#? What s the most elegant solution?

我可以这样做:

foreach(var obj in objects.OfType<IX>)
{
  var baseobj = (BaseObject)obj.DoStuff();
  obj.DoX();
}

但是,我发现这是很荒谬的。

而且,我可能需要将具体业务应用到实施第九章接口和界面的作业类型。

foreach(var obj in objects.OfType<BaseType and IX and IZ>)
{
  obj.DoStuff();
  obj.DoX();
  obj.DoZ();
}
最佳回答

一种可能的办法是使用<代码>动力学:

foreach(var xz in objects.Where(o => o is IX && o is IZ).Select(o => (dynamic)o))
{
    xz.DoStuff();
    xz.DoX();
    xz.DoZ();   
}

当然,如果你不想使用<条码>动力学,你仍然可以投放:

foreach(var xz in objects.Where(o => o is IX && o is IZ))
{
    xz.DoStuff();
    ((IX)xz).DoX();
    ((IZ)xz).DoZ(); 
}
问题回答

不可能做你想要的东西。

这里是你CAN所做的事。

首先,您只希望以实施<代码>IX、IY的类型操作? 然后,就把你的<代码>连接起来。 OfType methods. <代码>OfType将过滤下列名单:

foreach (var obj in objects.OfType<IX>().OfType<IY>().OfType<IZ>()) {

遗憾的是,<条码>obj将仅严格分类IZ,因为没有实施所有3个接口的类型。 因此,你仍然必须投放,但你再次保证,投放会发挥作用:

foreach (var obj in objects.OfType<IX>().OfType<IY>().OfType<IZ>()) {
    ((IX)obj).DoX();
    ((IY)obj).DoY();
    ((IZ)obj).DoZ(); // Note, You could also just do obj.DoZ(), but consistency looks better.
}

The most concise way to avoid a lot of casting and type testing is to introduce an extension method that handles it for you.

为此:

public static void DoAs<T>(this object @this, Action<T> action)
    where T : class
{
    var t = @this as T;
    if (t != null)
    {
        var a = action;
        if (a != null)
        {
            a(t);
        }
    }
}

现在,我以您的最后一例格言假定,如果标语同时执行<条码>、<九>/条码>和安页;<条码> IZ/条码>,你只希望执行该轮机。 因此,你将写:

foreach(var obj in objects)
{
    obj.DoAs<IX>(x =>
        x.DoAs<IZ>(z =>
        {
            obj.DoStuff();
            x.DoX();
            z.DoZ();
        }));
}

你的首批/中途停留并不需要任何新的推广方法,因为我认为这应当足够简单:

foreach(var obj in objects.OfType<IX>())
{
    (obj as BaseObject).DoStuff();
    obj.DoX();
}

我希望这一帮助。

采用这些课程和接口......

List<BaseObject> objects; 

class BaseObject 
{ 
  public void DoStuff(); 
} 

interface IX 
{ 
  public void DoX(); 
} 

interface IY 
{ 
  public void DoY(); 
} 

interface IZ 
{ 
  public void DoZ(); 
} 

class X : BaseObject, IX { }
class Y : BaseOjbect, IY { }
class Z : BaseObject, IZ {  }
class XY : BaseObject, IX, IY { }

摘自以上定义的任何<>Class

foreach (var o in objects)
{
  o.DoStuff();
  if (o is IX)
    ((IX)o).DoX(); //executed on class X and XY
  if (o is IY)
    ((IY)o).DoY(); //excuted on class Y and XY
  if (o is IZ)
    ((IZ)o).DoZ(); //excuted on class Z
}

我们应该做你们所期待的事情。

UPDATED per your comment.

foreach (var o in objects)
{
  o.DoStuff();
  if (o is IX and o is IY)
  {
    // do something different only for XY
  }
  else if (o is IX)
    ((IX)o).DoX(); //executed on class X 
  else if (o is IY)
    ((IY)o).DoY(); //excuted on class Y 
  else if (o is IZ)
    ((IZ)o).DoZ(); //excuted on class Z
}

<>蓬贝> 没有打字。

需要另一个接口。 (另外,DoStuff()应当放在所有第九、IY、IZ。)

interface IXY : IX, IY { }

//       This IXY could be var, but just strongly typing it for example
foreach (IXY o in objects.OfType(IXY)
                         .Cast<IXY>())
{
  o.DoStuff();
  o.DoX();
  o.DoY();
}

您也可以做一些选择:CRAZY:

foreach (var obj in objects.OfType<IX>()
                           .OfType<IY>()
                           .OfType<IZ>()
                           .Select(o => new 
                                   {
                                      AsIX = (IX)o,
                                      AsIY = (IY)o,
                                      AsIZ = (IZ)o
                                   }) 
{  
    obj.AsIX.DoX();  
    obj.AsIY.DoY();  
    obj.AsIZ.DoZ();
} 

在DoStuff。 您

if (this is IX) { (this as IX).DoX(); }

......,对于其他接口也是如此。





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签