<T,TU等的目的>

Cas*_*erT 1 c# generics

老实说,我不知道他们叫什么.我一直无法在互联网上找到文章.

所以我明白你可以这样做:

public struct Pair<T, U>
{
    public readonly T Value1;
    public readonly U Value2;

    public Pair(T fst, U snd)
    {
        this.Value1 = fst;
        this.Value2 = snd;
    }
    public override String ToString()
    {
        return "(" + Value1 + ", " + Value2 + ")";
    }
    public Pair<U, T> Swap()
    {
        return new Pair<U, T>(Value2, Value1);
    }
}
Run Code Online (Sandbox Code Playgroud)

它可能是一个class而不是一个struct.

但我很困惑,出于什么目的?某种性能提升?据我所知,您可以使用这些东西(抱歉,这是什么名称?)来保存值.但是你不会总是知道它应该拥有什么样的数据吗?例如:如果您需要存储产品,则只需制作产品类.当然,你知道它需要掌握什么样的数据,因为你正在设计代码.

所以是的,我想我的问题是:这个的目的是什么,与普通物体相比有什么优势; 您指定了更多

我想我不清楚.我也想知道:有没有充分的理由去创造像上面那样的东西?例如,一个更具体的对象,例如将产品数据存储在产品对象中,而不是一些可以接收所有内容的通用对象.

新:更多文本:另外,你怎么能处理完全通用的错误编码?当我不知道我必须处理什么样的数据类型时,我担心会进行任何类型的数学操作或实际上任何操作.如果它需要我为所有数据类型编写错误处理,那么我真的看不到这些通用参数的优点.

Dan*_*ker 8

假设您有两种情况,代码是相同的,除了代码中引用的类型之一是不同的.

能够将代码编写一次,然后在两种情况下使用相同的代码都不是很有用吗?例如,容器类就像List- 应该清楚的是,List每次要在其中存储特定类型时,必须编写不同的类会很麻烦.

它们被称为类型参数,需要参数的类型是泛型类型.

一个非常流行的数据结构是Dictionary<TKey, TValue>.它将键映射到值,因此您可以查找给定键的值.例如,密钥可能是"姓氏",值可能是"电话号码" - 在这种情况下,两者都是字符串类型(电话号码并不总是数字).

循环遍历a的内容时Dictionary,它存储的每个项目都是一对.在标准类中,类型是KeyValuePair<TKey, TValue>:

for (var pair in myDict)
{
    Console.WriteLine(pair.Key + " maps to " + pair.Value);
}
Run Code Online (Sandbox Code Playgroud)

  • 返回两个值? (2认同)
  • 有关使用通用Pair类的一些讨论,请参阅http://stackoverflow.com/questions/156275/what-is-the-equivalent-of-the-c-pairl-r-in-java/156685#156685 (2认同)
  • 我会说相反,最好尽可能少地指定*.如果有任何可能的方法可以避免在代码中指定某些内容,那么我不应该这样做.这样我的代码就变得尽可能灵活和通用.显然,如果我需要表示像产品一样具体的东西,那么是的,我*必须*指定其行为.没有办法解决这个问题,而且不应该存在.但是在编写List类时,为什么我必须指定它存储的对象类型?它应该能够存储我需要存储的任何东西. (2认同)

jal*_*alf 6

目的是通用性.通常,您有一个类,其行为并不真正取决于它所使用的类型.

而不是Pair考虑.NET类List<T>.它存储了某些类型的列表.该列表没有,也不应该关心它存储的类型.它只需要保证只能存储该类型.

A List<string>允许我存储字符串.A List<int>允许我存储整数.

如果我们没有泛型,我们必须抛弃类型安全,并使用一个只存储Object的类的List类,但是没有什么可以阻止我存储AppleBananas 列表中.

或者我们可以List为我们需要存储的每种类型编写一个新类.我们可以有ListOfApples,ListOfBananas,ListOfInts等.

我认为泛型提供了一个更好的解决方案.

这个Pair例子可能不太明显,因为often如果我们需要精确存储两个值,那是因为它们有一些明确的关系,应该通过创建一个特定的对象来表示.但有时,他们没有.有时它们只是"第一价值"和"第二价值".也许你有一个只返回两个值的函数.返回一个Pair<T1, T2,比返回一个值并通过一个out参数处理另一个更容易.

你经常不需要一双,没有.但是如果你真的需要"一种方法在单个对象中存储两个不同类型的值",如果没有与之关联的真实行为,那么一个Pair类很好地代表了它.然后,为什么不通过允许类型更改来使其可重用?

另外,你怎么能处理完全通用的错误编码?当我不知道我必须处理什么样的数据类型时,我担心会进行任何类型的数学操作或实际上任何操作.如果它需要我为所有数据类型编写错误处理,那么我真的看不到这些通用参数的优点.

简单:.NET不允许你这样做.在你的Pair示例中,如果你尝试使用一个不保证可用的函数,编译器会抱怨.在您的情况下,您将只能使用Object基类上定义的函数(当然,通用函数和类也适用于任何类型).

因此,您不能对这些泛型类型使用任何类型的数学操作.除了存储它们并传递它们(和调用.ToString())之外,你不能用它们做更多的事情.但有时候,你不需要更多的东西.例如,如果您只是创建一个List类,或者一个Pair.

您还可以指定约束,将其缩小一点.例如:

void DoStuffWithStream(T arg) where T : Stream
{
  // in this function that T is some type derived from Stream, so we can use all methods that would work on a Stream.
}
Run Code Online (Sandbox Code Playgroud)

如果我尝试使用a调用它,这将产生编译错误int,但是将适用于所有各种Stream子类.现在我对课程了解得更多,所以我将能够有意义地进行一些操作.

但是回到错误处理,你需要在List课堂上处理什么错误?不会发生很多错误.你有一个类,它的工作是存储一些未知(但固定)类型的可变数量的对象.它可以插入新对象(可能会抛出内存不足异常),并且可以检索对象.它可以让我们搜索对象,当然,当我们搜索到的东西找不到时,我们可能会遇到错误情况.但基本上就是这样.没有特定于泛型类型的错误处理.为什么会这样?我们不会对我们存储的对象执行任何类型特定的操作,因此它们实际上没有机会抛出任何特定于类型的错误.