Я нашел следующий модуль python-simplexml , который в попытках автора получить что-то похожее на SimpleXML из PHP действительно является small wrapper around ElementTree
. Это менее 100 строк, но, кажется, делает то, что было запрошено:
>>> import SimpleXml
>>> x = SimpleXml.parse(urllib.urlopen('http://www.google.com/ig/api?weather=94043'))
>>> print x.weather.current_conditions.temp_f['data']
58
Нет, вы не можете сделать это с помощью универсальных шаблонов C #. Однако вы могли бы сделать:
public static bool IsEnumFlagPresent<T>(T value, T lookingForFlag)
where T : struct
{
int intValue = (int) (object) value;
int intLookingForFlag = (int) (object) lookingForFlag;
return ((intValue & intLookingForFlag) == intLookingForFlag);
}
Это будет работать только для перечислений, у которых есть базовый тип int
, и это несколько неэффективно, потому что оно упаковывает значение ... но должно
Вы можете добавить проверку типа выполнения, что T действительно является типом перечисления (например, typeof (T) .BaseType == typeof (Enum)
)
Вот полная программа, демонстрирующая он работает:
using System;
[Flags]
enum Foo
{
A = 1,
B = 2,
C = 4,
D = 8
}
class Test
{
public static Boolean IsEnumFlagPresent<T>(T value, T lookingForFlag)
where T : struct
{
int intValue = (int) (object) value;
int intLookingForFlag = (int) (object) lookingForFlag;
return ((intValue & intLookingForFlag) == intLookingForFlag);
}
static void Main()
{
Console.WriteLine(IsEnumFlagPresent(Foo.B | Foo.C, Foo.A));
Console.WriteLine(IsEnumFlagPresent(Foo.B | Foo.C, Foo.B));
Console.WriteLine(IsEnumFlagPresent(Foo.B | Foo.C, Foo.C));
Console.WriteLine(IsEnumFlagPresent(Foo.B | Foo.C, Foo.D));
}
}
Вы хотите заменить одну строку кода функцией, которая завершает одну строку кода? Я бы сказал просто использовать одну строчку кода ...
Почему бы не написать для этого метод расширения? Я сделал это в другом посте
public static class EnumerationExtensions {
public static bool Has<T>(this System.Enum type, T value) {
try {
return (((int)(object)type & (int)(object)value) == (int)(object)value);
}
catch {
return false;
}
}
//... etc...
}
//Then use it like this
bool hasValue = permissions.Has(PermissionTypes.Delete);
Здесь можно было бы немного уточнить (поскольку предполагается, что все может быть преобразовано как int), но это может помочь вам начать ...
Вы можете сделать это без дженериков:
static bool ContainsFlags(Enum value, Enum flag)
{
if (Enum.GetUnderlyingType(value.GetType()) == typeof(ulong))
return (Convert.ToUInt64(value) & Convert.ToUInt64(flag)) == Convert.ToUInt64(flag);
else
return (Convert.ToInt64(value) & Convert.ToInt64(flag)) == Convert.ToInt64(flag);
}
В этом случае я конвертирую в Int64, который должен обрабатывать в каждом случае, кроме улонга, поэтому дополнительная проверка ...
Worth pointing out that simply providing some static overloads for all the integral types will work so long as you know you are working with a specific enum. They won't work if the consuming code is likewise operating on where t : struct
If you need to deal with arbitrary (struct) T
You cannot currently do a fast conversion of a generically typed struct into some alternate bitwise form (i.e. roughly speaking a reinterpret_cast) without using C++/CLI
generic <typename T>
where T : value class
public ref struct Reinterpret
{
private:
const static int size = sizeof(T);
public:
static int AsInt(T t)
{
return *((Int32*) (void*) (&t));
}
}
This will then let you write:
static void IsSet<T>(T value, T flags) where T : struct
{
if (!typeof(T).IsEnum)
throw new InvalidOperationException(typeof(T).Name +" is not an enum!");
Type t = Enum.GetUnderlyingType(typeof(T));
if (t == typeof(int))
{
return (Reinterpret.AsInt(value) & Reinterpret.AsInt(flags)) != 0
}
else if (t == typeof(byte))
{
return (Reinterpret.AsByte(value) & Reinterpret.AsByte(flags)) != 0
}
// you get the idea...
}
You cannot constrain to enums. But the mathematical validity of these methods do not change if they are used with non enum types so you could allow them if you can determine that they are convertible to a struct of the relevant size.
Что ж, я не верю, что есть способ сделать это, поскольку нет ограничений, которые применяются к поразрядным операторам.
Однако ... вы можете просто преобразовать enum в int и сделать это.
public static Boolean IsEnumFlagPresent(int value,int lookingForFlag)
{
return ((value & lookingForFlag) == lookingForFlag);
}
Это работает, но может кого-то запутать.
Я уже использовал это раньше:
public static bool In<T>(this T me, T values)
where T : struct, IConvertible
{
return (me.ToInt64(null) & values.ToInt64(null)) > 0;
}
Что мне нравится в этом, так это то, что вы можете использовать этот чистый синтаксис для его вызова, поскольку в 3.5 компилятор может вывести общие параметры.
AttributeTargets a = AttributeTargets.Class;
if (a.In(AttributeTargets.Class | AttributeTargets.Module))
{
// ...
}
Я недавно прочитал, что эта функция будет частью .NET 4.0. В частности, это реализовано в функции Enum.HasFlag ()
.
Вопрос давно закончился, но все же вот один для справки:
public static bool HasFlag<TEnum>(this TEnum enumeratedType, TEnum value)
where TEnum : struct, IComparable, IFormattable, IConvertible
{
if (!(enumeratedType is Enum))
{
throw new InvalidOperationException("Struct is not an Enum.");
}
if (typeof(TEnum).GetCustomAttributes(
typeof(FlagsAttribute), false).Length == 0)
{
throw new InvalidOperationException("Enum must use [Flags].");
}
long enumValue = enumeratedType.ToInt64(CultureInfo.InvariantCulture);
long flagValue = value.ToInt64(CultureInfo.InvariantCulture);
if ((enumValue & flagValue) == flagValue)
{
return true;
}
return false;
}