【问题标题】:Use only one method that accepts different typed parameters仅使用一种接受不同类型参数的方法
【发布时间】:2012-04-12 15:19:34
【问题描述】:

我有 3 个不同的数据库表,它们具有相同的 5 个字段,但它们没有任何外键关系,因为它们实际上并没有保持相同的值,而是等价的;比如:CompanyA 表有 productA,CompanyB 有 productB。

所以我有 3 个不同的集合,包括 3 个等效的字段。所以我想做的是使用具有 companyType 和 ProductName 属性的单个类,并仅使用一种方法将这 3 个不同的集合转换为一个且唯一的类对象,例如 ResultClass。

public class ResultClass
{
    public EnumCompanyType CompanyType { get; set; }
    public string ProductName { get; set; }

    public ICollection<ResultClass> ConvertAnything(ICollection<T> collection)
    {
        //Cast it to ResultClass

        return resultClassCollection;
    }
}

这样我就可以这样使用:

ICollection<ProductA> aCollection = GetCompanyAData();
ICollection<ProductB> bCollection = GetCompanyBData();        
ConvertAnything(aCollection);
ConvertAnything(bCollection);

我试过“动态”但实际上不知道原理(都不知道);所以我把它搞砸了,我认为它不适合这些东西。

我尝试创建一个扩展方法,但由于扩展没有其参数的类型(因为它使用 ICollection),我无法访问项目的字段(例如属性)

我用的是LinqToSql,所有的数据库表项等都属于这个概念,没有别的。

编辑:

我想我应该说清楚: 我试图避免的多个实例(或者我不应该,仍在思考)如下所示

public ICollection<ResultClass> ConvertAnythingForA(ICollection<ProductA> collection)
    {
        foreach(var item in collection)
        {
            var result = new ResultClass
                             {
                                 ProductName = item.ProductA,
                                 ProductType = EnumProductType.ProductA
                             };

            resultClassCollection.Add(result);
        }
        return resultClassCollection;
    }

public ICollection<ResultClass> ConvertAnythingForB(ICollection<ProductB> collection)
    {
        foreach(var item in collection)
        {
            var result = new ResultClass
                             {
                                 ProductName = item.ProductB,
                                 ProductType = EnumProductType.ProductB
                             };

            resultClassCollection.Add(result);
        }
        return resultClassCollection;
    }

提前致谢。

【问题讨论】:

    标签: c# linq-to-sql generics .net-3.5 casting


    【解决方案1】:

    我可能没有完全理解你,但由于 ProductA、ProductB 等具有相同的签名,所以你似乎想要一个像

    这样的界面
    public interface IResultClass
    {
        int CompanyType { get; set; }
        string ProductName { get; set; }
    }
    

    让这些类只实现接口。您可以使用可以具有各种类型对象的接口集合。如果您需要转换任何方法,它看起来像

    public ICollection<IResultClass> ConvertAnything<T>(ICollection<T> collection) where T : IResultClass
        {
            return collection.Select(x => (IResultClass)x).ToList();
        }
    

    在 cmets- 我看到你得到一个非通用的 ICollection 之后。你有没有尝试过这样的事情:

    public ICollection<IResultClass> ConvertAnything(ICollection collection)
        {
            var x = collection.Cast<IResultClass>();
            return x.ToList();
        }
    

    【讨论】:

    • 是的,我已经尝试过,正如我在问题中解释的那样,但是因为它是通用的,所以我无法访问属性;喜欢收藏[0].ProductName!而且它们没有完全相同的结构,它们具有不同名称且具有等效值的列
    • 这就是类型约束的原因。如果将其约束到接口,则可以访问接口中定义的任何内容。
    • 所以我猜这不是我的解决方案?
    • 在您所做的编辑中,我无法理解它如何确定如何将其转换为 IResultClass?
    • Cast 返回 IEnumerable,如果它无法将集合中的项目转换为 T,则会引发运行时异常。因此,如果您的产品类都可以实现相同的接口(或从相同的基类派生)。 (这个 cast 方法只是一个捷径——你可以编写自己的代码来做同样的事情)。
    【解决方案2】:

    您可能想要使用函数重载。此示例使用不同数量的参数,但您也可以轻松地使用不同的类型。

    http://csharp.net-tutorials.com/classes/method-overloading/

    【讨论】:

    • 那样,我不会创建 3 个完全相同的方法,而是创建一个具有完全相同的三倍内容的方法,对吗?
    【解决方案3】:

    如果两个数据集是等价的,为什么不只使用一种称为 ICollection 的类型呢?还有一个功能,例如。 “GetProductData(“A”)”,其中“A”/“B”是参数?还是我错过了什么?

    【讨论】:

    • 它们有相同的字段和不同的字段,所以它们不是一个表。
    • 好的。您可以创建一个 Product 类来继承每种类型的接口(例如 IProductA、IProductB 等)。然后,ConvertAnything 必须弄清楚每种产品类型要做什么。您可以通过重载来做到这一点(这样它就可以提前知道要获得什么产品类型)。或者您对其进行编码以自行确定,然后在转换之前将 Product 转换为适当的类型。
    猜你喜欢
    • 2016-09-23
    • 2012-06-02
    • 2016-01-25
    • 2016-09-18
    • 1970-01-01
    • 2011-07-06
    • 1970-01-01
    • 1970-01-01
    • 2012-06-18
    相关资源
    最近更新 更多