【问题标题】:how to achieve the generic input parameter property name in foreach looping如何在foreach循环中实现通用输入参数属性名
【发布时间】:2019-02-06 12:57:12
【问题描述】:

如何循环遍历一个泛型参数方法?

我有一个通用方法的集合。

public void DoSomething<T>(List<T> input)
{
    // I want to foreach
    foreach (var v in input)
    {
        byte[] data = v.Data;
        string name = v.Name;
    }
}

我的问题是:我没有在 V 中得到数据和名称。它是通用的。如何实现它

【问题讨论】:

  • 你为什么选择List&lt;T&gt;,而不是List&lt;Foo&gt;Foo 是你的类,它具有DataName 属性?是因为您有多种类型,它们都具有DataName 属性吗?
  • public void DoSomething&lt;T&gt;(List&lt;T&gt; input) where T: IFooT 实现了IFoo,它提供了Dataname 属性
  • 您可以放弃泛型并执行DoSomething(IEnumerable&lt;IFoo&gt; input) 之类的操作,因为IEnumerable 是协变的,您可以将实现接口的任何内容与实现IFoo 的项目一起传递。
  • @juharr:对不起,我怕我不懂这些,哈哈,我是新手
  • 如果您看一下洋葱架构之类的概念,将业务对象(也称为域实体)制作成整个架构共享的领域实体并不是一个坏做法。如果您保持业务对象简单(只是数据桶,我的导师过去常说),并在架构的正确部分(即不在业务对象本身)实现功能,那么这个概念将非常强大和灵活。跨度>

标签: c# .net list generics c#-4.0


【解决方案1】:

您可以让所有通用输入实现一个接口,该接口公开您需要的属性。然后,您需要对泛型 T 施加约束,以便使用这些属性:

void Main()
{
    var list = new List<RandomData>();

    DoSomething(list);
}

public void DoSomething<T>(List<T> input) where T : IData
{
    foreach(var v in input)
    {
        byte[] data = v.Data;
        string name = v.Name;
    }
}

public interface IData
{
    byte[] Data { get; set; }

    string Name { get; set; }
}

class RandomData : IData
{
    public byte[] Data { get; set; }

    public string Name { get; set; }
}

【讨论】:

  • 看起来不错,但违背了我创建泛型的全部目的。我的要求非常非常简单,不是脑洞大开的东西。我只是制作了一个类可重用库(它不会有我的任何业务反对意见,在本例中为 RandomData)。我不想在 Reusable 组件中引用 Business Objects 项目 DLL,反之亦然。所以如果我必须这样做,我什至不必让它通用
  • @Learner 如果不以某种方式引用它们,您将无法使用您的业务对象。编译器应该如何知道你要做什么。
  • 我只是想了一下。这是否意味着,您希望我在同一个可重用类库项目中创建此属性接口和实现的类?你的意思是和我的业务对象一样吗?
  • 您的意思是可重用类中我的业务对象的副本,以便当我从外部调用时它只接受......
  • 其实这是我的第一个泛型方法,10年来对泛型的理解哈哈。现在我实际上在某种程度上明白了。 :) 到现在为止,只是为了面试,我理论上理解,但理解不能用手打字。从心态上讲,我是一名业务分析师,但别无选择,只能为面包编码。所以感谢你,因为我真的学到了今天的感受,我很自豪看到我编写的一些花哨的东西哈哈......
【解决方案2】:

您要实现的是创建一个通用方法,该方法迭代某些特定类型以执行某些特殊操作,在这种情况下,这将是因为共享的共同行为,因此创建泛型没有附加价值如果它们之间没有共同点,则迭代特定成员以执行某些操作的方法,因此在您的情况下,您可以在泛型类型上设置条件以实现接口:

public void DoSomething<T>(List<T> input) where T : ICommonLogic
{
    foreach(var v in input)
    {
        byte[] data = v.Data;
        string name = v.Name;
    }
}

甚至可以通过添加扩展来更简洁:

public static class CommonLogicExtensions
{
   public static DoSomething(this IEnumerable<ICommonLogic> input)
   {
        foreach(var v in input)
        {
            byte[] data = v.Data;
            string name = v.Name;
        }
   }
}

泛型的使用有些不同,例如创建一个采用不同类型对象的数据结构,如List,但当涉及特定或特殊行为时,应使用通用接口。

【讨论】:

  • 它看起来很花哨,我是外行哈哈我不明白:(但你的看起来高保真......对不起我是初级......
猜你喜欢
  • 1970-01-01
  • 2021-02-07
  • 1970-01-01
  • 2012-04-10
  • 1970-01-01
  • 1970-01-01
  • 2019-07-23
  • 1970-01-01
  • 2013-08-19
相关资源
最近更新 更多