C# ';为什么';和';其中';是否实际使用了泛型?
我知道泛型是用来实现类型安全的,我经常读到它们主要用于定制集合。但为什么我们真的需要通用呢 比如说, 为什么我不能使用C# ';为什么';和';其中';是否实际使用了泛型?,c#,.net,generics,C#,.net,Generics,我知道泛型是用来实现类型安全的,我经常读到它们主要用于定制集合。但为什么我们真的需要通用呢 比如说, 为什么我不能使用string[]而不是List 让我假设一个泛型类,它有一个泛型类型参数x.< /p> T x; 如果我为类提供一个方法 x = x + 1; 这到底是什么意思?我不知道t实际将是什么,也不知道x=x+1实际将执行什么 如果我不能在我的方法中进行我自己的操作,那么泛型将如何帮助我呢 我已经研究了很多书生气的答案。如果有人能在这方面提供一些清晰的见解,我们将不胜感激 问候,,
string[]
而不是List
让我假设一个泛型类,它有一个泛型类型参数x.< /p>
T x;
如果我为类提供一个方法
x = x + 1;
这到底是什么意思?我不知道t
实际将是什么,也不知道x=x+1
实际将执行什么
如果我不能在我的方法中进行我自己的操作,那么泛型将如何帮助我呢
我已经研究了很多书生气的答案。如果有人能在这方面提供一些清晰的见解,我们将不胜感激
问候,,
NLV当我们需要“高阶”多态性时,我们使用泛型,类似于编译时。当我们说
Foo
时,我们的意思是Foo
依赖于任何可能的T
可以具有的某些属性,并且给定的T
具有该属性,或者代码无法编译
当我们说x=x+1
时,我们意味着T
能够添加1
,返回类型是T
但为什么我们真的需要通用呢
如果您愿意,还可以创建许多自定义类:StringList
、IntList
、DoubleList
,等等。。但是泛型的要点是,您可以定义一次类,它适用于所有对象
而
x=x+1
其中x
是泛型T
需要实际的实数类型来支持或自然添加int,或者让操作符+
重载int作为第二种类型。对于第一个问题,您可以选择List
而不是string[]
如果要向列表中动态添加字符串-数组的大小是固定的。因为虽然支持字符串[](即扣除自定义数组类型),但数组具有:
*功能不如列表,甚至不如IList
*是数组,因此这不适用于其他类型的集合。字典呢
如果我不能自己做
我的方法中的操作
仿制药会帮助我的
无论如何
这有点像问“如果我经营一家素食餐厅,我能在我的供应商那里买到牛排有什么好处?”
基本上,当项目变得更复杂时,您将在方法中编写自己的操作。你会在有意义的地方做所有的事情。public foobar{
public foobar<T>{
public Action<string,T> SomeAction;
public string SomeString;
public foobar(Action<string,T> s,string m){
SomeAction=s;
SomeString=m;
}
public void Run(T foo){
SomeAction(SomeString,foo);
}
}
公共行动;
公共字符串SomeString;
公共foobar(动作s,字符串m){
SomeAction=s;
SomeString=m;
}
公众假期跑步(T-foo){
SomeAction(SomeString,foo);
}
}
如果没有泛型,您将不得不为每种可能的情况编写不同的类,或者进行一些其他精细的操作以获得所需的结果。泛型让事情变得更优雅。事实上,我正在一个atm网站上工作,在那里泛型让我的工作更轻松。我需要从数据库访问大量信息,因为整个站点都是数据库驱动的,所以我真的希望有一个类来实现数据库功能。这个类被更多知道如何处理各自数据的类继承 例如,我有一个处理产品数据的Products类和一个处理主题的Themes类,等等。,。所有这些课程都需要一种通用的阅读和写作格式。所以,我创建了一个记录类来处理这个问题 现在,泛型的乐趣从这里开始。我创建了一个产品类、主题类等。,。对于强类型成员,例如Name、Manufacturer、ThemeId,Records类不知道如何处理它们。因此,数据库类被实例化为与特定类、产品、主题等相关的类型。,。Record类也使用泛型类型,因此我可以编写如下代码
Product.Name = "Cool Product";
然后把它像
Products.InsertRecord(Product coolProduct);
它不仅节省了大量的输入,而且使我能够拥有一个处理所有脏活的类,而这些小的“存根”类为我提供了一个可读的强类型接口
不管怎样,我为这篇冗长的文章感到抱歉。希望这至少能帮助您理解泛型在这种情况下的威力。
string[]
为我们提供了一个固定大小的数组。要获得动态大小的列表,我们需要一个类。因此,如果我们想要一个字符串列表,我们可能必须创建一个名为StringList的类。双打,双打名单。等等但是,这些类对于这些类型来说是唯一的呢?没有什么。因此,我们创建了一个泛型类List,它可以接受任何类型。泛型不必为不同的类型一次又一次地重新创建同一个类,它为我们节省了一些工作
至于x=x+1
问题,您必须预期T有一个+
操作符,它在右侧接受int。如果没有,它将抛出一个运行时错误。如果是,则该代码将把x分配给+
运算符的输出,并将x
和1
作为参数
在许多其他情况下,没有执行唯一的操作,并且类/方法必须处理多个类型。在这些情况下,泛型也很重要和有用
在代码中何时何地使用它们实际上取决于您自己。如果你遇到一个问题,他们是最好的答案,很好。使用它们。否则,不要。只是不要取消它们作为解决方案的资格,因为它们从来都不是您特定问题的答案。根据我自己的工作经验,管理Linq到SQL类型就是一个很好的例子。创建网元时必须执行的一个基本操作
public class SQLObjectManager<TEntity> where TEntity : class, new()
{
public TEntity GetObject(int year, int stateID)
{
if( /* entity found in cache */)
return GetFromCache(year,stateID);
if( /* entity found in db */)
return GetFromDB(year,stateID);
TEntity entity = new TEntity();
entity.Year = year;
entity.StateID = stateID;
return entity;
}
}
MyGenericStack<string> stringStack = new MyGenericStack<string>();
stringStack.Push("One");
stringStack.Push("Two");
stringStack.Push("Three");
MyGenericStack<int> intStack = new MyGenericStack<int>();
intStack.Push(1);
intStack.Push(2);
intStack.Push(3);
MyGenericStack<CustomObject> customObjectStack = new MyGenericStack<CustomObject>();
customObjectStack.Push(new CustomObject(1));
customObjectStack.Push(new CustomObject(2));
customObjectStack.Push(new CustomObject(3));
public class MyGenericStack<T>
{
int position;
T[] data = new T[10];
public void Push(T obj) { data[position++] = obj; }
public T Pop() { return data[--position]; }
public void Show()
{
for (int i = 0; i < data.Length; i++)
{
//Console.WriteLine("Item: {0}", data[i]);
//MessageBox.Show(String.Format("Item: {0}", data[i]));
}
}
}