Implicit or explicit conversion from T to T []

Is there a way to implement a generic implicit or explicit converter for something into an array of something like:

public static implicit operator T[](T objToConvert) { return new T[] { objToConvert }; } 
+4
source share
6 answers

Operator overload methods must be inside the class in which they override the operators (one or the other). Since "T" is not defined, I do not see how this can be done.

+1
source

Not. The closest I can think of is an extension method:

 public static T[] AsArray<T>(this T instance) { return new T[]{instance}; } 

Use as:

 var myArray = myInstnace.AsArray(); 
+7
source

Note that you can omit the type name from the array constructor, which means that the syntax is pretty clean, even with a long type name:

 ReallyLongAndAwkwardTypeName value; MethodThatTakesArray(new[] {value}); 
+7
source

You can do this with the usual method:

 public static T[] ToArray<T>(T objToConvert) { return new T[] { objToConvert }; } 

I do not think you can define a generics operator. In any case, note that the compiler only needs to copy to guess the type of the general parameter, so you can use:

 var aString=""; var aStringArray=ToArray(aString); 

aStringArray is defined as a string array, even if you do not specify a generic parameter.

0
source

I tried to think of situations where you really can use implicit conversion to an array. I began to wonder if many situations can be alleviated when you want to do this using the params keyword.

The main situation that I could think of was that you had one element of something and he wanted to pass it to a function that takes an array as a parameter:

  static void Main(string[] args) { string x = "I'm just a poor variable. Nobody loves me."; Stickler.IOnlyTakeArrays_Rawr111(x); // won't go in! square peg, round hole, etc. // *sigh* fine. Stickler.IOnlyTakeArrays_Rawr111(new[] { x }); } class Stickler { public static void IOnlyTakeArrays_Rawr111(string[] yum) { // ... } } 

I hope that in this situation, the author of the method you want to call selected params to use the keyword so that you can pass your variable without wrapping it into an array:

  class DataConcierge { public static T Create<T>(int id) { // ... } public static void Save<T>(params T[] items) { // ... } } static void Main(string[] args) { var customer = DataConcierge.Create<Customer>(123); // ... DataConcierge.Save(customer); // this works! //---------------------------------------------------- // or //---------------------------------------------------- var customers = new Customer[] { DataConcierge.Create<Customer>(123), DataConcierge.Create<Customer>(234), DataConcierge.Create<Customer>(345), }; // ... DataConcierge.Save(customers); // this works too! } 

Of course, this will not help you in situations where you need to convert a variable into a single array of elements, but not as a parameter for a method or in situations where the author of the method did not use the params keyword.

But what would be the first situation? Array assignment for a property? Psh. How often does this happen?

And the last? If the author did not use the params keyword when they could do this, send them a letter complaining about it. If the author himself, feel free to be an additional warrior in the letter.

I hope you can say that I am doing well. Seriously, however, are there other common usage situations that you can think of where the params keyword will not apply?

** Disclaimer: I am not a supporter of the excessive use of the params keyword. Use it if you think you want, but do not accept my message so you always use the params keyword whenever you can.

0
source

In the past, I used the Conductor concept (my own name for it), which is just a class / structure that provides access to a base value.

The concept is useful for abstracting access to a specific value obtained from somewhere. For example, if you want to abstract access to a specific value in a dictionary, you can create a wire object that contains a link to the dictionary and the corresponding key for that value. You can also use this concept to easily implement rollback for serializable classes or value types, although for this you will need to add rollback and command methods to the explorer class / structure.

Below is an example of how you can use implicit conversions from T to conductor and from conductor to T [] to (kind of) achieve what you want.

  static void Main(string[] args) { // implicit conversion here from Customer to Conductor<Customer> Conductor<Customer> conductor = DataConcierge.Create<Customer>(123); if (conductor.HasValue) { Console.WriteLine("I got a customer with Id {0}!", conductor.Value.Id); // implicit conversion here from Conductor<Customer> to Customer[] DataConcierge.Save<Customer>(conductor); } } public struct Conductor<T> : IConductor<T>, IEquatable<T>, IEquatable<Conductor<T>>, IEquatable<IConductor<T>> { private T _Value; public Conductor(T value) { this._Value = value; } public T Value { get { return this._Value; } set { this._Value = value; } } public bool HasValue { get { return this._Value != null; } } public T GetValueOrDefault() { if (this.HasValue) return this.Value; else return default(T); } public T GetValueOrDefault(T @default) { if (this.HasValue) return this.Value; else return @default; } public bool TryGetValue(out T value) { if (this.HasValue) { value = this.Value; return true; } else { value = default(T); return false; } } public T[] AsArray() { return new T[] { this._Value }; } public static implicit operator Conductor<T>(T value) { return new Conductor<T>(value); } public static implicit operator T(Conductor<T> conductor) { return conductor.Value; } public static implicit operator T[](Conductor<T> conductor) { return conductor.AsArray(); } public bool Equals(T other) { var otherEquatable = other as IEquatable<T>; if (otherEquatable != null) return otherEquatable.Equals(this.Value); else return object.Equals(this.Value, other); } public bool Equals(Conductor<T> other) { if (other.HasValue) return this.Equals(other.Value); else return !this.HasValue; } public bool Equals(IConductor<T> other) { if (other != null && other.HasValue) return this.Equals(other.Value); else return !this.HasValue; } public override bool Equals(object obj) { if (obj == null) return !this.HasValue; var conductor = obj as IConductor<T>; if (conductor != null) { if (conductor.HasValue) return this.Equals(conductor.Value); else return !this.HasValue; } return object.Equals(this.Value, obj); } public override int GetHashCode() { if (this.HasValue) return this.Value.GetHashCode(); else return 0; } public override string ToString() { if (this.HasValue) return this.Value.ToString(); else return null; } } 
0
source

All Articles