使用约束类型泛型与使用基类型定义方法 [英] Define method with Constrained Type Generic vs. Using Base Type

查看:125
本文介绍了使用约束类型泛型与使用基类型定义方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近的一次讨论发生在我们试图辨别以下哪种情况会更好的工作中。



我们的域名有一个基本类型,其中很多从它继承的类:

  public abstract class DomainBase 
{
public int BaseId {get;组;在代码中的另一个地方,我们有一个方法,它接受一组代码的对象,并基于 BaseId 进行工作。它不会返回对象或以其他方式使用给定的类型。



我的问题:在这里使用泛型更好吗? ,或只是在基类型?



选项A:无效DoWork< TDomainBase>(List< TDomainBase>对象)其中TDomainBase:DomainBase;选项B: void DoWork(List< DomainBase> objects);



在我们的代码中,这些被调用的是相同的,因为我们从来没有使用具有不同类型的 List< DomainBase> 集合(例如新列表< DomainBase> {new Foo(),new Bar()} )。我想说使用泛型更好一些,以便在将它们传递给方法时,不会隐式地将 objects 转换为它们的基类。但我想确保我在这里不会错过任何明显的东西。 (或者说,C#可能只是在引擎盖下优化所有这些,而不管我选择哪个选项!)很高兴被证明是错误的。



编辑删除不正确的语句。

解决方案

两个选项都应该可以工作 - 好的,几乎正确。



使用通用选项,您可以直接将您的基本类型或任何从其派生的
类型的列表直接传递给方法:

$ bDo
$ b pre $ void $ DoWork< TDomainBase>(List< TDomainBase> objects)其中TDomainBase:DomainBase
...
...
var list = new List< SomeClassDerivedFromDomainBase>(){/ * initialize items * /};

DoWork(list);

但是,使用基类列表,您必须执行一个额外的步骤并生成该列表从您的派生类型列表:

 无效DoWork(List< DomainBase>对象); 

var list = new List< SomeClassDerivedFromDomainBase>(){/ * initialize items * /};

DoWork(list); //这将导致编译错误:
//不能隐式地将类型'System.Collections.Generic.List< SomeClassDerivedFromDomainBase>'转换为'System.Collections.Generic.List< DomainBase>'

您将得到编译错误的原因在列表< Derived> 分配给一个 List< Base>



要解决此问题,您必须执行以下操作:

  DoWork(list.ToList< DomainBase>()); 

我认为现在应该很清楚,在这种情况下,通用选项更好。


A discussion came up recently at work where we were trying to discern which of the following would be better.

We have a base type for our domain, with many classes inheriting from it:

public abstract class DomainBase
{
    public int BaseId { get; set; }
}

In another spot in code, we have a method that takes in a set of objects and does work based on BaseId. It doesn't return the objects back or otherwise use the type given at all.

My question: Is it better to use a generic here, or just take in the base types?

Option A: void DoWork<TDomainBase>(List<TDomainBase> objects) where TDomainBase : DomainBase;

Option B: void DoWork(List<DomainBase> objects);

In our code these are called the same, as we never work with List<DomainBase> that have different types i the collection (e.g. new List<DomainBase> { new Foo(), new Bar() }). I want to say that using the generic is better, so that we don't implicitly convert objects to their base class when passing them into the method. But I want to make sure I'm not missing something obvious here. (Or, heck, C# might just optimize all this away under the hood regardless of which option I choose!) Happy to be proven wrong.

Edited to remove incorrect statement.

解决方案

"Both options should work" - Well, that's almost correct.

Using the generic option your can simply pass a list of your base type or any type that derives from it to the method directly:

void DoWork<TDomainBase>(List<TDomainBase> objects) where TDomainBase : DomainBase
...
...
var list = new List<SomeClassDerivedFromDomainBase>() {/* initialize items */};

DoWork(list);

However, using a list of base class, you will have to do one extra step and generate that list from your list of derived types:

void DoWork(List<DomainBase> objects);

var list = new List<SomeClassDerivedFromDomainBase>() {/* initialize items */};

DoWork(list); // This will cause a compilation error:
// Cannot implicitly convert type 'System.Collections.Generic.List<SomeClassDerivedFromDomainBase>' to 'System.Collections.Generic.List<DomainBase>'

The reason you will get the compilation error is explained in the answers to Why can't I assign a List<Derived> to a List<Base>?

To work around it, you will have to do something like this:

DoWork(list.ToList<DomainBase>());

I think it should be pretty clear by now that the generic option is better in this case.

这篇关于使用约束类型泛型与使用基类型定义方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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