C# 如何隐式地对自定义对象强制转换LINQ查询的结果?

C# 如何隐式地对自定义对象强制转换LINQ查询的结果?,c#,linq,list,collections,casting,C#,Linq,List,Collections,Casting,我正在从事一个使用大量自定义类的项目,每个自定义类有效地表示数据库中的一行数据。当存在多个数据元素时,我一直在这样做: public class Client { private int _clientID; private double _annualRevenue; public int ClientID { get { return _clientID; } set { _clientID = value; } }

我正在从事一个使用大量自定义类的项目,每个自定义类有效地表示数据库中的一行数据。当存在多个数据元素时,我一直在这样做:

public class Client
{
    private int _clientID;
    private double _annualRevenue;

    public int ClientID
    {
        get { return _clientID; }
        set { _clientID = value; }
    }

    public double AnnualRevenue
    {
        get { return _annualRevenue; }
        set { _annualRevenue = value; }
    }
}
然后,在代码的其他地方

public class QueryClients
{

    private List<Client> _clients;

    public List<Client> FindClientByRevenue(double minimumRevenue)
    {
        List<Client> returnValue = (from c in _clients
                                    where c.AnnualRevenue >= minimumRevenue
                                    select c).ToList();

        return returnValue;
    }

}
…我得到一个编译器错误:

CS0266
Cannot implicitly convert type 'System.Collections.Generic.List<Client>' to 'Clients'. An explicit conversion exists (are you missing a cast?)  
代码甚至编译得很好。但我一问这个问题,它就爆炸了

        Clients clients = new Clients();
        Client client;

        client = new Client();
        client.ClientID = 1;
        client.AnnualRevenue = 100;
        clients.Add(client);

        client = new Client();
        client.ClientID = 2;
        client.AnnualRevenue = 200;
        clients.Add(client);

        client = new Client();
        client.ClientID = 3;
        client.AnnualRevenue = 300;
        clients.Add(client);

        QueryClients q = new QueryClients(clients);

        Clients clients2 = q.FindClientByRevenue(200);
当然,这是一个铸造错误

An unhandled exception of type 'System.InvalidCastException' occurred.

Additional information: Unable to cast object of type 'System.Collections.Generic.List`1[Client]' to type 'Clients'.
因此,即使它编译,它也不会运行,即使这种方法确实有效,它也不能真正解决我的问题,因为这样我就必须显式地强制转换每个LINQ查询的结果,如果必须这样做,我还不如到处声明列表。唉

所以不管怎么说,我做错了什么,我就是不知道该怎么做。我确信,至少,我需要向我的Clients类添加一个转换/强制转换操作符,以允许隐式转换发生(或其他)。我尝试了很多不同的东西,基于无数不同的谷歌搜索,它要么无法编译,要么无法运行。我就是搞不懂

有两个目标:

1.)在我的代码中使用Clients对象,而不必反复声明列表变量

2.)能够运行LINQ查询,从一个客户机对象选择一些客户机对象到另一个(新)客户机对象

这可能吗?你能告诉我如何修改Clients类以使其工作(隐式转换)吗?如果能做到的话,我相信这很简单,我会因为自己在发布之前没有看到它而责备自己


提前感谢您提供的见解。

很抱歉,我要更改以下内容:

public class QueryClients
{
    private List<Client> _clients;

    public List<Client> FindClientByRevenue(double minimumRevenue)
    {
        List<Client> returnValue = (from c in _clients
                                where c.AnnualRevenue >= minimumRevenue
                                select c).ToList();

        return returnValue;
    }
}
公共类查询客户端
{
私人名单客户;
公共列表FindClientByRevenue(最低收入加倍)
{
List returnValue=(来自c in_客户机
其中c.年收入>=最低收入
选择c.ToList();
返回值;
}
}
为此:

public class QueryClients
{
    private Clients _clients;

    public List<Client> FindClientByRevenue(double minimumRevenue)
    {
        Clients returnValue = (from c in _clients
                                where c.AnnualRevenue >= minimumRevenue
                                select c).ToList();

        return returnValue;
    }
}
公共类查询客户端
{
私人客户(u客户),;
公共列表FindClientByRevenue(最低收入加倍)
{
Clients returnValue=(来自c in_Clients
其中c.年收入>=最低收入
选择c.ToList();
返回值;
}
}
毫无意义。
您希望以与
列表
完全相同的方式使用类型
客户端

因此,如果您继续使用
列表
,并享受通用
列表
可能带来的所有好处,似乎会更好。

警告:不要这样做,坚持使用
列表
,但出于教育原因,以下是答案


您有很多选择,首先是让类将
IEnumerable


另一种方法是提供一个显式强制转换,从
IList
执行大致相同的操作,但您必须将
客户机
类更改为不继承
列表


您会得到强制转换异常,因为列表查询结果的动态类型是
list
,而不是从中继承的客户端(当对象实际上不是“狗”时,您不能从“动物”强制转换为“狗”)

由于不能从基类进行任何用户定义的转换,我建议删除继承并添加隐式(或显式)转换:

公共类客户端{
私人名单d;
公共客户(名单d)
{
this.d=d.ToList();
}
公共静态隐式运算符客户端(列表d)
{
返回新客户(d);
}
}
但是,这不允许您将客户端视为可枚举的。或者,您可以使用以下签名将扩展方法写入
IEnumerable

  public static Clients ToClientList(this IEnumerable<Client> input){
     return new Clients(input);
  } 
publicstaticclientstoclientlist(此IEnumerable输入){
返回新客户(输入);
} 

作为旁注,我认为使用
列表
比定义自己的类更优雅、更清晰。

您应该创建一个.dbml文件,该文件链接到您的数据库,您可以在该文件上添加您希望模型类查询数据库的所有SQL表。这也将自动生成类,而无需编写一行代码。之后,您可以修改从数据库查询的该模型的实例并提交更改。没有一个SQL查询需要写入以更新或删除。一切都由LINQ处理

下面是一个很好的演练:

一切设置完成后,您需要做的就是: //创建数据上下文

MyDataContext=新的MyDataContext(myConnectionString)

//查询一些客户机-客户机类将由LINQ自动生成

Listclients=(从上下文中的Client.clients where CONDITON select Client).ToList()

//根据需要修改这些客户端 //提交对数据上下文的更改(将从此数据上下文自动更新修改的类)


context.SubmitChanges()

简单:使用
List
(并在适当的情况下使用
IEnumerable
)。不要把时间浪费在疯狂的特技上,以避免使用尖括号而牺牲可读性,即使你可以让它工作。你的时间花在吸食大麻上比写这段代码更有益。为什么它很难看?这只是泛型。通过习惯语法,您将获得更多里程数。就我个人而言,我宁愿知道变量是
IEnumerable
而不是
Clients
。尽可能使用
var
。泛型的思想是减少所需的类的数量。基本上,您希望返回到.Net 1。在我看来,使用这样的类型名称可以使代码更具可读性,但我一直是疯狂特技之王。我想我已经在这上面浪费了两天了(因为这里的每个人都同意在任何地方使用括号都是answ
public class QueryClients
{
    private List<Client> _clients;

    public List<Client> FindClientByRevenue(double minimumRevenue)
    {
        List<Client> returnValue = (from c in _clients
                                where c.AnnualRevenue >= minimumRevenue
                                select c).ToList();

        return returnValue;
    }
}
public class QueryClients
{
    private Clients _clients;

    public List<Client> FindClientByRevenue(double minimumRevenue)
    {
        Clients returnValue = (from c in _clients
                                where c.AnnualRevenue >= minimumRevenue
                                select c).ToList();

        return returnValue;
    }
}
public class Clients : List<Client>
{
    public Clients(IEnumerable<Client> clients) 
        : base(clients){}
}
Clients returnValue = new Clients(from c in _clients
                                    where c.AnnualRevenue >= minimumRevenue
                                    select c);
public class Clients 
{
    private  List<Client> list;
    public Clients(IEnumerable<Client> clients) 
    { this.list = clients.ToList(); }

    public static explicit operator Clients(List<Client> list)
    {
          return new Clients(list);
    }
}
 Clients returnValue = (Clients)(from c in _clients
                                    where c.AnnualRevenue >= minimumRevenue
                                    select c).ToList();
public class Clients {
    private List<Client> d;

    public Clients(List<Client> d)
    {
        this.d = d.ToList();
    }

    public static implicit operator Clients(List<Client> d)
    {
        return new Clients(d);
    }
}
  public static Clients ToClientList(this IEnumerable<Client> input){
     return new Clients(input);
  }