Welcome to mirror list, hosted at ThFree Co, Russian Federation.

Extensions.cs « Xamarin.PropertyEditing - github.com/xamarin/Xamarin.PropertyEditing.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: e3efa54307e877c0991b8cf70d8f50311c030562 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Xamarin.PropertyEditing
{
	internal static class Extensions
	{
		public static void AddItems<T> (this ICollection<T> self, IEnumerable items)
		{
			if (items == null)
				throw new ArgumentNullException (nameof (items));

			IEnumerable<T> enumerable = items as IEnumerable<T> ?? items.Cast<T>();

			List<T> list = self as List<T>;
			if (list != null) {
				list.AddRange (enumerable);
				return;
			}

			ObservableCollectionEx<T> observable = self as ObservableCollectionEx<T>;
			if (observable != null) {
				observable.AddRange (enumerable);
				return;
			}

			foreach (T item in enumerable)
				self.Add (item);
		}

		public static object ElementAt (this IEnumerable self, int index)
		{
			if (self == null)
				throw new ArgumentNullException (nameof (self));
			if (index < 0)
				throw new ArgumentOutOfRangeException (nameof(index));

			if (self is IList list)
				return list[index];

			int i = 0;
			foreach (object element in self) {
				if (i++ == index)
					return element;
			}

			throw new ArgumentOutOfRangeException (nameof(index));
		}

		public static int Count (this IEnumerable self)
		{
			if (self == null)
				throw new ArgumentNullException (nameof (self));

			if (self is ICollection collection)
				return collection.Count;

			int count = 0;
			foreach (object element in self)
				count++;

			return count;
		}

		/// <summary>
		/// Replaces the first instance of <paramref name="replace"/> with <paramref name="with"/>, or adds it if <paramref name="replace"/> isn't found.
		/// </summary>
		public static void ReplaceOrAdd<T> (this ICollection<T> self, T replace, T with)
		{
			if (self == null)
				throw new ArgumentNullException (nameof (self));

			IList<T> list = self as IList<T>;
			if (list != null) {
				int i = list.IndexOf (replace);
				if (i != -1)
					list[i] = with;
				else
					list.Add (with);

				return;
			}

			self.Remove (replace);
			self.Add (with);
		}

		public static void Move (this IList self, int index, int moveTo)
		{
			if (self == null)
				throw new ArgumentNullException (nameof(self));

			if (index < moveTo)
				moveTo--;

			object item = self[index];
			self.RemoveAt (index);
			self.Insert (moveTo, item);
		}

		public static bool TryRemove<TKey, TElement> (this IDictionary<TKey, TElement> self, TKey key, out TElement element)
		{
			if (!self.TryGetValue (key, out element))
				return false;

			self.Remove (key);
			return true;
		}

		public static bool Contains (this string self, string value, StringComparison comparison)
		{
			if (self == null)
				throw new ArgumentNullException (nameof(self));

			return self.IndexOf (value, comparison) >= 0;
		}

		public static async Task<AssignableTypesResult> GetCommonAssignableTypes (this IEnumerable<IObjectEditor> editors, IPropertyInfo property, bool childTypes)
		{
			if (editors == null)
				throw new ArgumentNullException (nameof(editors));
			if (property == null)
				throw new ArgumentNullException (nameof(property));

			List<ITypeInfo> suggested = null;
			HashSet<ITypeInfo> all = null;
			var tasks = new HashSet<Task<AssignableTypesResult>> (editors.Select (oe => oe.GetAssignableTypesAsync (property, childTypes)));

			while (tasks.Count > 0) {
				var task = await Task.WhenAny (tasks).ConfigureAwait (false);
				tasks.Remove (task);

				if (suggested == null) {
					suggested = new List<ITypeInfo> (task.Result.SuggestedTypes ?? Enumerable.Empty<ITypeInfo>());
					all = new HashSet<ITypeInfo> (task.Result.AssignableTypes);
					continue;
				}

				all.IntersectWith (task.Result.AssignableTypes);

				foreach (ITypeInfo type in suggested.ToArray()) {
					if (!task.Result.AssignableTypes.Contains (type))
						suggested.Remove (type);
				}
			}

			return new AssignableTypesResult (suggested, all);
		}
	}
}