3

I have a generic class, Class<T>, that implements IEnumerable<T>. T is also constrained to implement IConvertable.

I also want this class to be able to pretend to be a string-like object, so I want to implement IEnumerable<char>. However, IEnumerable<T> and IEnumerable<char> collide -- what happens if T is char?

Does anyone have any suggestions on how to accomplish this?

EDIT: Here's some clarification -- I'd like to be able to do the following:

public IEnumerator<T> GetEnumerator()
{
    for (var i = _offset; i < _offset + _length; i++)
        yield return _array[i];
}

public IEnumerator<char> GetEnumerator()
{
    for (var i = _offset; i < _offset + _length; i++)
        yield return _array[i].ToChar(null);
}
6
  • 1
    did you try to implement just IEnumerable<T> and check if T is char inside the implementation? would this work? Commented Nov 16, 2010 at 16:52
  • 1
    connect.microsoft.com/VisualStudio/feedback/details/334054/… Commented Nov 16, 2010 at 16:55
  • Whats the other usages of this class? to make it generic? Commented Nov 16, 2010 at 17:02
  • As I can see you have GetEnumerator method, which is differ in act with char, there is no need create such a class for example you can have a list<T> which implements all above, I'm saying what is the thing your class wants to implement to create it, and if there is reason to create your class, why you decide create it generic? Commented Nov 16, 2010 at 17:16
  • @Saeed: I don't understand what you're saying. Commented Nov 16, 2010 at 17:21

3 Answers 3

10

Does anyone have any suggestions on how to accomplish this?

Declaration of generic types such that the base types can unify under construction is sometimes illegal and almost always a bad idea. Avoid, avoid, avoid.

My advice: if you want an object that acts like a string then either override ToString(), or declare an explicit (or, I suppose, implicit) conversion to string. If the user wants a sequence of chars then they can obtain one from the string.

Sign up to request clarification or add additional context in comments.

8 Comments

I'm trying to avoid the new object generation from producing a string. I just need to have string-like behavior.
what about implicit operators?
Implicit or explicit, there's still a new object.
@David: And so you're using IEnumerable<char> to avoid creating a new object? How do you plan on avoiding creating an object for the IEnumerator when the sequence of chars (or T's) is enumerated?
@Brian: I think what David is getting at is that his pooling strategy is that when the enumerator object is disposed, then it can be "reset" and stuffed back into the pool. It's a slightly scary but reasonably common technique for avoiding memory allocations if you are in an environment where you are highly sensitive to GC pressure. Which it sounds like he is.
|
2

You say that you need your class to "pretend to be a string-like object". Can you make the string-like behaviour more explicit and avoid implementing IEnumerable<char> at all?

public IEnumerator<T> GetEnumerator()
{
    for (var i = _offset; i < _offset + _length; i++)
        yield return _array[i];
}

// either
public IEnumerator<char> GetCharEnumerator()
{
    for (var i = _offset; i < _offset + _length; i++)
        yield return _array[i].ToChar(null);
}

// or
public IEnumerable<char> AsCharSequence()
{
    for (var i = _offset; i < _offset + _length; i++)
        yield return _array[i].ToChar(null);
}

1 Comment

Woah, wait a second... you can use yield to return IEnumerable as well as IEnumerator?
1
public class myClass<T>() : IEnuerable<T> where T: IConvertable
{
 public override string ToString()
 {
  if(typeof(T).Equals(typeof(char)))
   return this.Select(obj => obj.ToChar(null).ToString()).Aggregate((cur, nex) => cur + "," + nex);;
  else
   return this.Select(obj => obj.ToString()).Aggregate((cur, nex) => cur + "," + nex);
 }
}

or u could just use extension method

public static class extension
{
 public static string To_String<T>(this IEnumerable<T> data) where T:IConvertable
 {
  if(typeof(T).Equals(typeof(char)))
   return data.Select(obj => obj.ToChar(null).ToString()).Aggregate((cur, nex) => cur + "," + nex);;
  else
   return data.Select(obj => obj.ToString()).Aggregate((cur, nex) => cur + "," + nex);
 }
}

or just put if

public IEnumerator<T> GetEnumerator()
{
  if(typeof(T).Equals(typeof(char)))
    for (var i = _offset; i < _offset + _length; i++)
        yield return _array[i].ToChar(null);
  else
    for (var i = _offset; i < _offset + _length; i++)
        yield return _array[i];
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.