gpt4 book ai didi

c# - 通用 IList 的 "type"是什么?

转载 作者:行者123 更新时间:2023-11-30 20:20:32 24 4
gpt4 key购买 nike

想象一下这样的扩展..

public static Blah<T>(this IList<T> ra)
{
..
}

假设您想记下最近调用的一个。

private static IList recent;
public static Blah<T>(this IList<T> ra)
{
recent = ra;
..
}

你实际上不能那样做:

error CS0266: Cannot implicitly convert type System.Collections.Generic.IList<T> to System.Collections.IList.

1- 你可以简单地制作 recent一个object这似乎工作正常,但似乎是一个糟糕的解决方案。

2- 看来你最近有一个 IList ,您实际上可以将“ra”转换为...

recent = (System.Collections.IList)ra;

它似乎有效。虽然看起来很奇怪??所以,

3- 实际上,最近应该 什么类型,这样您就不必强制转换为它??你怎么做recentra 相同的类型?你不能这么说....

private static System.Collections.Generic.IList recent;

没有意义。那么“ra”的类型到底是什么?应该做什么recent "be"这样你就可以简单地说 recent=ra

(我提到这是针对 Unity 的,因为您经常在 Unity 中使用通用扩展。)


4- 如果你想拥有所有这些的字典,请考虑一个更困难的情况。

private static Dictionary<object,int> recents = new Dictionary<object,int>();

我真的只能看到如何将它作为一个对象来实现。


用例示例。

这是您在游戏工程中随处不断使用的扩展,

public static T AnyOne<T>(this IList<T> ra)
{
int k = ra.Count;
if (k<=0) {Debug.Log("Warn!"+k);}
int r = UnityEngine.Random.Range(0,k);
return ra[r];
}

目前没问题。所以,

explosions.AnyOne();
yetAnotherEnemyToDefeat = dinosaurStyles.AnyOne();

等等。然而。当然,实际的随机选择感觉很糟糕;实际上,您想要的是相当不重复的顺序,更像是随机播放。通常,对任何列表或数组做的最好的事情就是将它们打乱顺序,然后按顺序提供它们;也许每次都重新洗牌。简单的例子,你有 20 个随机音效 roars ,当恐龙咆哮时。每次你需要一个,如果你这样做

 roars.AnyOne();

还可以,但不是很好。这听起来有点糟糕。 (大多数玩家会反馈为“不随机”或“重复很多”。)这

 roars.NextOne();

好多了。所以,NextOne()应该,就其本身而言,(a) 如果我们在开始时将列表洗牌,(b) 按该顺序提供它,(c) 也许每次你用完列表时再次洗牌。 {还有一些更微妙的地方,例如,尽量不要在重组结束/开始时重复任何内容,但这里无关紧要。}

请注意,由于许多显而易见的原因,子类化列表(和/或数组)会很糟糕,这是一个简单的独立扩展的工作。

那么,这里有一个实现NextOne()的绝妙方法使用简单的有状态扩展。

private static Dictionary<object,int> nextOne = new Dictionary<object,int>();
public static T NextOne<T>(this IList<T> ra)
{
if ( ! nextOne.ContainsKey(ra) )
// i.e., we've never heard about this "ra" before
nextOne.Add(ra,0);

int index = nextOne[ra];

// time to shuffle?
if (index==0)
{
Debug.Log("shuffling!"); // be careful to mutate, don't change the ra!
IList<T> temp = ra.OrderBy(r => UnityEngine.Random.value).ToList();
ra.Clear(); foreach(T t in temp) ra.Add(t);
}

T result = ra[index];
++index;
index=index%ra.Count;
nextOne[ra] = index;
return result;
}

这无疑是“有状态扩展”的完美示例。

请注意,我只是用了“object”。

我想在某种程度上,这个 QA 的基本问题是,最好是在那里使用“object”字典,还是其他更类型化的东西会更好?真的是这样手头的问题。干杯!

最佳答案

如果你想要一个全局最新的IList<T>其中 T可能每次都不同,那么你唯一的选择就是使用 objectdynamic .两者都需要类型转换;后者只是自动转换。

我认为您的困惑源于认为 IList<T>继承IList - it doesn't :

public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable

所以可以说你可以这样做,虽然我真的没有看到任何优势:

private static IEnumerable recent;
public static void Blah<T>(this IList<T> ra)
{
recent = ra;
...
}

关于c# - 通用 IList<T> 的 "type"是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36243382/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com