如何从索引器中获取值数组?

时间:2021-05-30 04:15:25

I'm using a class that has an indexer defined and would like to get the data out of it and into a simple array. Is there a better way than looping through the indexer?

我正在使用一个已定义索引器的类,并希望从中获取数据并将其转换为简单数组。有没有比循环索引器更好的方法?

The indexer:

public class MyIndexer
{
    public int Foo { get; }
    public int GetSize{ get; }  //size of data vector
    public float this[int idx] { get; set; }
}

Something like this would be nice:

像这样的东西会很好:

float[] data = indexer.GetData();

Note that I can't change MyIndexer.

请注意,我无法更改MyIndexer。

3 个解决方案

#1


1  

Since you can get the number of elements, you can create an extension method:

由于您可以获得元素数量,因此可以创建扩展方法:

public static float[] GetData(this MyIndexer indexer)
{
    return Enumerable.Range(0, indexer.GetSize).Select(i => indexer[i]).ToArray();
}

You could also just use a for loop:

你也可以使用for循环:

public float[] GetData(this MyIndexer indexer)
{
    float[] data = new float[indexer.GetSize];
    for(int i = 0; i < data.Length; i++)
    {
        data[i] = indexer[i];
    }
}

#2


1  

No, there is no other way than to loop through the indexes. There are many ways to do the looping, but no way around it.

不,没有其他方法可以循环索引。循环有很多种方法,但没办法解决。

Also, looping through the indexes only works if the indexer actually can return values for the indexes that you expect it to. Just because the class has an indexer doesn't mean that it has to be implemented to handle any specific indexes.

此外,仅当索引器实际上可以返回您期望它的索引的值时,循环索引才有效。仅仅因为类具有索引器并不意味着必须实现它来处理任何特定索引。

#3


0  

From what you have there, looping would be the only way.

从你拥有的东西,循环将是唯一的方式。

I'd be pretty annoyed at the developer of the class though. There are conventions in .NET that are backed up by well known interfaces; ICollection, ICollection<T>, IList, IList<T> being particularly apt.

不过,我对班上的开发人员非常恼火。 .NET中有一些约定由众所周知的接口支持; ICollection,ICollection ,IList,IList 特别适合。

While arrays and string's use of Length is a near-exception, the only reason I can think of for calling GetSize, "GetSize" (or indeed, for calling a property anything in the form "GetXXX") is if I knew the person who would be using the class, and I really disliked them. Not implementing ICollection<float> is a bit more likely to be justifiable, but it still is something to justify with a good reason, rather than just not bothering.

虽然数组和字符串使用Length是一个接近异常,但我能想到调用GetSize的唯一原因,“GetSize”(或者实际上,用于调用“GetXXX”形式的任何属性)是我认识的人会使用这个课程,我真的不喜欢他们。没有实现ICollection 更有可能是合理的,但它仍然有充分理由证明是合理的,而不仅仅是没有打扰。

Since most classes of this nature would implement ICollection<float>, in most cases where this comes up you'd be able to do:

由于这种性质的大多数类都会实现ICollection ,因此在大多数情况下,你可以这样做:

float[] arr = new float[indexer.Count];
indexer.CopyTo(arr, 0);

But most bizarre still is the fact that it doesn't even implement IEnumerable<float>. That's really, really weird. It's such a core part of .NET ways of doing things, that unless there's a really good reason, it's bordering on being a bug-of-omission. If it had, then you could have just done index.ToArray().

但最奇怪的是,它甚至没有实现IEnumerable 。那真的非常奇怪。它是.NET做事方式的核心部分,除非有一个非常好的理由,否则它就像是一个遗漏的错误。如果有,那么你可以刚刚完成index.ToArray()。

If I had to work with this object much, I'd probably write a wrapper class or at least a set of extension methods to fill in the gaps.

如果我不得不使用这个对象,我可能会编写一个包装类或至少一组扩展方法来填补空白。

#1


1  

Since you can get the number of elements, you can create an extension method:

由于您可以获得元素数量,因此可以创建扩展方法:

public static float[] GetData(this MyIndexer indexer)
{
    return Enumerable.Range(0, indexer.GetSize).Select(i => indexer[i]).ToArray();
}

You could also just use a for loop:

你也可以使用for循环:

public float[] GetData(this MyIndexer indexer)
{
    float[] data = new float[indexer.GetSize];
    for(int i = 0; i < data.Length; i++)
    {
        data[i] = indexer[i];
    }
}

#2


1  

No, there is no other way than to loop through the indexes. There are many ways to do the looping, but no way around it.

不,没有其他方法可以循环索引。循环有很多种方法,但没办法解决。

Also, looping through the indexes only works if the indexer actually can return values for the indexes that you expect it to. Just because the class has an indexer doesn't mean that it has to be implemented to handle any specific indexes.

此外,仅当索引器实际上可以返回您期望它的索引的值时,循环索引才有效。仅仅因为类具有索引器并不意味着必须实现它来处理任何特定索引。

#3


0  

From what you have there, looping would be the only way.

从你拥有的东西,循环将是唯一的方式。

I'd be pretty annoyed at the developer of the class though. There are conventions in .NET that are backed up by well known interfaces; ICollection, ICollection<T>, IList, IList<T> being particularly apt.

不过,我对班上的开发人员非常恼火。 .NET中有一些约定由众所周知的接口支持; ICollection,ICollection ,IList,IList 特别适合。

While arrays and string's use of Length is a near-exception, the only reason I can think of for calling GetSize, "GetSize" (or indeed, for calling a property anything in the form "GetXXX") is if I knew the person who would be using the class, and I really disliked them. Not implementing ICollection<float> is a bit more likely to be justifiable, but it still is something to justify with a good reason, rather than just not bothering.

虽然数组和字符串使用Length是一个接近异常,但我能想到调用GetSize的唯一原因,“GetSize”(或者实际上,用于调用“GetXXX”形式的任何属性)是我认识的人会使用这个课程,我真的不喜欢他们。没有实现ICollection 更有可能是合理的,但它仍然有充分理由证明是合理的,而不仅仅是没有打扰。

Since most classes of this nature would implement ICollection<float>, in most cases where this comes up you'd be able to do:

由于这种性质的大多数类都会实现ICollection ,因此在大多数情况下,你可以这样做:

float[] arr = new float[indexer.Count];
indexer.CopyTo(arr, 0);

But most bizarre still is the fact that it doesn't even implement IEnumerable<float>. That's really, really weird. It's such a core part of .NET ways of doing things, that unless there's a really good reason, it's bordering on being a bug-of-omission. If it had, then you could have just done index.ToArray().

但最奇怪的是,它甚至没有实现IEnumerable 。那真的非常奇怪。它是.NET做事方式的核心部分,除非有一个非常好的理由,否则它就像是一个遗漏的错误。如果有,那么你可以刚刚完成index.ToArray()。

If I had to work with this object much, I'd probably write a wrapper class or at least a set of extension methods to fill in the gaps.

如果我不得不使用这个对象,我可能会编写一个包装类或至少一组扩展方法来填补空白。