Используя метод расширения для маленьких вспомогательных задач, что (АВ)использует тот факт, что объект не разыменовывается


Недавно я получил в привычку, где я использовал расширение методов для придания вещи владеют свойствами - например, ниже пример или другой пример сущности.AssertNotNull()

public static class GenericHelper
{
    public static void AssignOrThrowIfNull<T>(this T obj, ref T assignTo, string paramName)
    {
        if (obj == null)
            throw new ArgumentNullException(paramName, "Unallowed null argument of type: " + typeof(T).FullName);
        assignTo = obj;
    }
}

Затем это используется следующим образом:

public class SmtpClient

public SmtpServerAddress Server
{
    get { return smtpServer; }
}

private SmtpServerAddress smtpServer;

public SmtpClient(SmtpServerAddress smtpServer)
{
    smtpServer.AssignToOrThrow(ref this.smtpServer, "smtpServer");
}

в отличие от

public SmtpClient(SmtpServerAddress smtpServer)
{
    if(smtpServer == null)
        throw new ArgumentNullException("smtpServer");
}

Вы думаете, что это читается? Это в любом случае предпочтительнее регулярных проверок везде? Тот факт, что я не могу решить, если мне нравится или не заставляет меня нервничать, так что я бы что-нибудь из внешнего входа!

Обновление:

Да, ты заставил меня открыть глаза. Надеюсь, вы согласитесь со мной, что немного более приятным. Я использовал выражения, потому что я хочу включить как можно больше информации в исключения.

public static class Require
{
    public static void That(Expression<Func<bool>> func)
    {
        if (!func.Compile()())
            throw new ContractException("Contract not fulfilled: " + func.Body, func);
    }
}

По крайней мере я думаю, что это делает его немного яснее, хотя лямбда синтаксис не очень приятно (я не думаю, что параметр smtpserver != значение null может быть выведено выражение).

Require.That(() => smtpServer != null);
SmtpServer = smtpServer;

Поскольку я скомпилировать выражение каждый раз, там, безусловно, будет падение производительности.



1597
3
задан 8 июля 2011 в 07:07 Источник Поделиться
Комментарии
4 ответа

Вы можете захотеть взглянуть на код контракты , что позволяет написать:

Contract.Requires<ArgumentNullException>(smtpServer != null);

Это выражает четко, что вы пытаетесь сделать, и имеет дополнительное преимущество, позволяя дополнительные статические проверки кода инструмента контракты, чтобы проверить код, который вызывает метод из-за возможных нарушений договора.

3
ответ дан 9 июля 2011 в 11:07 Источник Поделиться

Я думаю, что твое чутье тебя не подводит, мне не нравится это и это, кажется, за архитектуру. Общая схема проверки если параметр имеет значение null и исключение хорошо известна и программисты к этому привыкли - настолько, что они смогут понять его быстрым взглядом. Ваш переделанный вариант необычен и поэтому им придется ступить на способ и посмотреть на него.

Методы расширения являются фантастическим в целом, но я не думаю, что это правильное использование одним.

1
ответ дан 8 июля 2011 в 08:07 Источник Поделиться

Не сделать код короче.

Не было понятнее кому-то, кто является новым в ваш код.

Если бы было больше логики в метод расширения, может быть. Но в данном случае - нет.

1
ответ дан 9 июля 2011 в 10:07 Источник Поделиться

Я же предлагаю вам использовать дженерики, а не дженерики, а также специальным чехлом для универсального класса обработки исключений. Это все об использовании анонимных функций, методы расширения и статические функции.

Я whould бы suggust вы использовать прототипирование с помощью Функ и Функ за невыполнение общих и универсальных методов соответственно;

Кроме того, вам не потребуется устанавливать CodeContracts использовать договор requrents.
После применения следующий исходный код, читаемость кода может значительно улучшить, и имеют более элегантный вид, нежели чувствовали:

public SmtpClient(SmtpServerAddress smtpServer, bool dummy1, bool dummy2) 
{
Server = smtpServer
.RequireNotNull()
.RequireIsNullOrWhitespace((obj) => obj.UNC)
.RequireEqualsZero((obj) => obj.UID);
}

или (полных источников):

public class SmtpClient
{
public SmtpServerAddress Server { get; private set; }
public SmtpClient(SmtpServerAddress smtpServer)
{
AssertionContracts.ThrowOnTrue<ArgumentNullException>(() => smtpServer == null);
Server = smtpServer;
}
public SmtpClient(SmtpServerAddress smtpServer, bool dummy1, bool dummy2)
{
smtpServer
.RequireNotNull()
.RequireIsNullOrWhitespace((obj) => obj.UNC)
.RequireEqualsZero((obj) => obj.UID);
Server = smtpServer;
}
}

public class SmtpServerAddress
{
public string UNC { get; set; }
public long UID { get; set; }
}

Исходный код:

public static class AssertionContracts
{
private static class Exceptions<U> where U : Exception, new()
{
public static T ThrowOnTrue<T>(T obj, Func<T, bool> function, params object[] args)
{
if (function(obj) == true)
{
Throw(obj, args);
}
return obj;
}
public static T ThrowOnFalse<T>(T obj, Func<T, bool> function, params object[] args)
{
if (function(obj) == false)
{
Throw(obj, args);
}
return obj;
}
public static void Throw<T>(T obj, params object[] args)
{
throw CreateException(obj, args);
}
private static U CreateException<T>(T obj, params object[] args)
{
return (U)Activator.CreateInstance(typeof(U), args);
}
}
public class ContractException : Exception
{
public ContractException() : base() { }
public ContractException(string message) : base(message) { }
protected ContractException(SerializationInfo info, StreamingContext context) : base(info, context) { }
public ContractException(string message, Exception innerException) : base(message, innerException) { }
}
public static T ThrowOnTrue<T, U>(this T obj, Func<T, bool> function, params object[] args) where U : Exception, new()
{
return AssertionContracts.Exceptions<ContractException>.ThrowOnTrue(obj, function);
}
public static T ThrowOnFalse<T, U>(this T obj, Func<T, bool> function, params object[] args) where U : Exception, new()
{
return AssertionContracts.Exceptions<ContractException>.ThrowOnFalse(obj, function);
}
public static void Throw<T, U>(this T obj, Func<T, bool> function, U ex) where U : Exception
{
AssertionContracts.Exceptions<ContractException>.Throw(obj, function);
}
public static T NoThrowContractException<T>(this T obj, Func<T, bool> function)
{
return AssertionContracts.Exceptions<ContractException>.ThrowOnTrue(obj, function);
}
public static T ThrowContractException<T>(this T obj, Func<T, bool> function)
{
return AssertionContracts.Exceptions<ContractException>.ThrowOnFalse(obj, function);
}
public static T AssertTrue<T>(this T obj, Func<T, bool> function)
{
Trace.Assert(function(obj) == true);
return obj;
}
public static T AssertFalse<T>(this T obj, Func<T, bool> function)
{
Trace.Assert(function(obj) == false);
return obj;
}
public static T AssertIsNullOrEmpty<T>(this T obj, Func<T, string> function)
{
Trace.Assert(string.IsNullOrEmpty(function(obj)));
return obj;
}
public static T AssertIsNullOrWhitespace<T>(this T obj, Func<T, string> function)
{
Trace.Assert(string.IsNullOrWhiteSpace(function(obj)));
return obj;
}
public static T AssertIsNotNullOrEmpty<T>(this T obj, Func<T, string> function)
{
Trace.Assert(!string.IsNullOrEmpty(function(obj)));
return obj;
}
public static T AssertIsNotNullOrWhitespace<T>(this T obj, Func<T, string> function)
{
Trace.Assert(!string.IsNullOrWhiteSpace(function(obj)));
return obj;
}
public static T AssertEquals<T, U>(this T obj, Func<T, U> function, U value)
{
Trace.Assert(object.Equals(function(obj), value));
return obj;
}
public static T AssertNotEquals<T, U>(this T obj, Func<T, U> function, U value)
{
Trace.Assert(!object.Equals(function(obj), value));
return obj;
}
public static T AssertDefault<T, U>(this T obj, Func<T, U> function)
{
Trace.Assert(object.Equals(function(obj), default(U)));
return obj;
}
public static T AssertNonDefault<T, U>(this T obj, Func<T, U> function)
{
Trace.Assert(!object.Equals(function(obj), default(U)));
return obj;
}
public static T AssertNotNull<T, U>(this T obj, Func<T, U> function)
{
Trace.Assert(!object.Equals(function(obj), default(U)));
return obj;
}
public static T AssertNotNull<T>(this T obj)
{
Trace.Assert(!object.Equals(obj, default(T)));
return obj;
}
public static T AssertNull<T, U>(this T obj, Func<T, U> function)
{
Trace.Assert(object.Equals(function(obj), default(U)));
return obj;
}
public static T AssertNull<T>(this T obj)
{
Trace.Assert(object.Equals(obj, default(T)));
return obj;
}
public static T AssertPositive<T>(this T obj, Func<T, int> function)
{
Trace.Assert(function(obj) > 0);
return obj;
}
public static T AssertPositive<T>(this T obj, Func<T, long> function)
{
Trace.Assert(function(obj) > 0);
return obj;
}
public static T AssertNegative<T>(this T obj, Func<T, int> function)
{
Trace.Assert(function(obj) < 0);
return obj;
}
public static T AssertNegative<T>(this T obj, Func<T, long> function)
{
Trace.Assert(function(obj) < 0);
return obj;
}
public static T AssertEqualsZero<T>(this T obj, Func<T, int> function)
{
Trace.Assert(function(obj) == 0);
return obj;
}
public static T AssertEqualsZero<T>(this T obj, Func<T, long> function)
{
Trace.Assert(function(obj) == 0);
return obj;
}
public static T AssertNotEqualsZero<T>(this T obj, Func<T, int> function)
{
Trace.Assert(function(obj) != 0);
return obj;
}
public static T AssertNotEqualsZero<T>(this T obj, Func<T, long> function)
{
Trace.Assert(function(obj) != 0);
return obj;
}
public static T AssertGreaterThan<T>(this T obj, Func<T, int> function, int value)
{
Trace.Assert(function(obj) > value);
return obj;
}
public static T AssertGreaterThan<T>(this T obj, Func<T, long> function, long value)
{
Trace.Assert(function(obj) > value);
return obj;
}
public static T AssertLessThan<T>(this T obj, Func<T, int> function, int value)
{
Trace.Assert(function(obj) < value);
return obj;
}
public static T AssertLessThan<T>(this T obj, Func<T, long> function, long value)
{
Trace.Assert(function(obj) < value);
return obj;
}
public static T AssertGreaterOrEqualsThan<T>(this T obj, Func<T, int> function, int value)
{
Trace.Assert(function(obj) >= value);
return obj;
}
public static T AssertGreaterOrEqualsThan<T>(this T obj, Func<T, long> function, long value)
{
Trace.Assert(function(obj) >= value);
return obj;
}
public static T AssertLessOrEqualsThan<T>(this T obj, Func<T, int> function, int value)
{
Trace.Assert(function(obj) <= value);
return obj;
}
public static T AssertLessOrEqualsThan<T>(this T obj, Func<T, long> function, long value)
{
Trace.Assert(function(obj) <= value);
return obj;
}
public static T AssertGreaterOrEqualsZero<T>(this T obj, Func<T, int> function)
{
Trace.Assert(function(obj) >= 0);
return obj;
}
public static T AssertGreaterOrEqualsZero<T>(this T obj, Func<T, long> function, long value)
{
Trace.Assert(function(obj) >= 0);
return obj;
}
public static T AssertLessOrEqualsZero<T>(this T obj, Func<T, int> function)
{
Trace.Assert(function(obj) <= 0);
return obj;
}
public static T AssertLessOrEqualsZero<T>(this T obj, Func<T, long> function)
{
Trace.Assert(function(obj) <= 0);
return obj;
}
public static T RequireTrue<T>(this T obj, Func<T, bool> function)
{
return obj.ThrowContractException((o) => function(obj) == true);
}
public static T RequireFalse<T>(this T obj, Func<T, bool> function)
{
return obj.ThrowContractException((o) => function(obj) == false);
}
public static T RequireIsNullOrEmpty<T>(this T obj, Func<T, string> function)
{
return obj.ThrowContractException((o) => string.IsNullOrEmpty(function(obj)));
}
public static T RequireIsNullOrWhitespace<T>(this T obj, Func<T, string> function)
{
return obj.ThrowContractException((o) => string.IsNullOrWhiteSpace(function(obj)));
}
public static T RequireIsNotNullOrEmpty<T>(this T obj, Func<T, string> function)
{
return obj.ThrowContractException((o) => !string.IsNullOrEmpty(function(obj)));
}
public static T RequireIsNotNullOrWhitespace<T>(this T obj, Func<T, string> function)
{
return obj.ThrowContractException((o) => !string.IsNullOrWhiteSpace(function(obj)));
}
public static T RequireEquals<T, U>(this T obj, Func<T, U> function, U value)
{
return obj.ThrowContractException((o) => object.Equals(function(obj), value));
}
public static T RequireEquals<T, U>(this T obj, T value)
{
return obj.ThrowContractException((o) => object.Equals(obj, value));
}
public static T RequireNotEquals<T, U>(this T obj, Func<T, U> function, U value)
{
return obj.ThrowContractException((o) => !object.Equals(function(obj), value));
}
public static T RequireNotEquals<T, U>(this T obj, T value)
{
return obj.ThrowContractException((o) => !object.Equals(obj, value));
}
public static T RequireDefault<T, U>(this T obj, Func<T, U> function)
{
return obj.ThrowContractException((o) => object.Equals(function(obj), default(U)));
}
public static T RequireDefault<T>(this T obj)
{
return obj.ThrowContractException((o) => object.Equals(obj, default(T)));
}
public static T RequireNonDefault<T, U>(this T obj, Func<T, U> function)
{
return obj.ThrowContractException((o) => !object.Equals(function(obj), default(U)));
}
public static T RequireNonDefault<T, U>(this T obj)
{
return obj.ThrowContractException((o) => !object.Equals(obj, default(T)));
}
public static T RequireNotNull<T, U>(this T obj, Func<T, U> function)
{
return obj.ThrowContractException((o) => !object.Equals(function(obj), default(U)));
}
public static T RequireNotNull<T>(this T obj)
{
return obj.ThrowContractException((o) => !object.Equals(obj, default(T)));
}
public static T RequireNull<T, U>(this T obj, Func<T, U> function)
{
return obj.ThrowContractException((o) => object.Equals(function(obj), default(U)));
}
public static T RequireNull<T>(this T obj)
{
return obj.ThrowContractException((o) => object.Equals(obj, default(T)));
}
public static T RequirePositive<T>(this T obj, Func<T, int> function)
{
return obj.ThrowContractException((o) => function(obj) > 0);
}
public static T RequirePositive<T>(this T obj, Func<T, long> function)
{
return obj.ThrowContractException((o) => function(obj) > 0);
}
public static T RequireNegative<T>(this T obj, Func<T, int> function)
{
return obj.ThrowContractException((o) => function(obj) < 0);
}
public static T RequireNegative<T>(this T obj, Func<T, long> function)
{
return obj.ThrowContractException((o) => function(obj) < 0);
}
public static T RequireEqualsZero<T>(this T obj, Func<T, int> function)
{
return obj.ThrowContractException((o) => function(obj) == 0);
}
public static T RequireEqualsZero<T>(this T obj, Func<T, long> function)
{
return obj.ThrowContractException((o) => function(obj) == 0);
}
public static T RequireNotEqualsZero<T>(this T obj, Func<T, int> function)
{
return obj.ThrowContractException((o) => function(obj) != 0);
}
public static T RequireNotEqualsZero<T>(this T obj, Func<T, long> function)
{
return obj.ThrowContractException((o) => function(obj) != 0);
}
public static T RequireGreaterThan<T>(this T obj, Func<T, int> function, int value)
{
return obj.ThrowContractException((o) => function(obj) > value);
}
public static T RequireGreaterThan<T>(this T obj, Func<T, long> function, long value)
{
return obj.ThrowContractException((o) => function(obj) > value);
}
public static T RequireLessThan<T>(this T obj, Func<T, int> function, int value)
{
return obj.ThrowContractException((o) => function(obj) < value);
}
public static T RequireLessThan<T>(this T obj, Func<T, long> function, long value)
{
return obj.ThrowContractException((o) => function(obj) < value);
}
public static T RequireGreaterOrEqualsThan<T>(this T obj, Func<T, int> function, int value)
{
return obj.ThrowContractException((o) => function(obj) >= value);
}
public static T RequireGreaterOrEqualsThan<T>(this T obj, Func<T, long> function, long value)
{
return obj.ThrowContractException((o) => function(obj) >= value);
}
public static T RequireLessOrEqualsThan<T>(this T obj, Func<T, int> function, int value)
{
return obj.ThrowContractException((o) => function(obj) <= value);
}
public static T RequireLessOrEqualsThan<T>(this T obj, Func<T, long> function, long value)
{
return obj.ThrowContractException((o) => function(obj) <= value);
}
public static T RequireGreaterOrEqualsZero<T>(this T obj, Func<T, int> function)
{
return obj.ThrowContractException((o) => function(obj) >= 0);
}
public static T RequireGreaterOrEqualsZero<T>(this T obj, Func<T, long> function, long value)
{
return obj.ThrowContractException((o) => function(obj) >= 0);
}
public static T RequireLessOrEqualsZero<T>(this T obj, Func<T, int> function)
{
return obj.ThrowContractException((o) => function(obj) <= 0);
}
public static T RequireLessOrEqualsZero<T>(this T obj, Func<T, long> function)
{
return obj.ThrowContractException((o) => function(obj) <= 0);
}
public static void ThrowOnFalse<U>(Func<bool> function, params object[] args) where U : Exception, new()
{
if (function() == false)
{
throw (U)Activator.CreateInstance(typeof(U), args);
}
}
public static void ThrowOnTrue<U>(Func<bool> function, params object[] args) where U : Exception, new()
{
if (function() == true)
{
throw (U)Activator.CreateInstance(typeof(U), args);
}
}
public static void Throw<U>(Func<bool> function, U ex) where U : Exception
{
if (function() == false)
{
throw ex;
}
}
public static void AssertTrue(Func<bool> function)
{
Trace.Assert(function() == true);
}
public static void AssertFalse(Func<bool> function)
{
Trace.Assert(function() == false);
}
public static void AssertIsNullOrEmpty(Func<string> function)
{
Trace.Assert(string.IsNullOrEmpty(function()));
}
public static void AssertIsNullOrWhitespace(Func<string> function)
{
Trace.Assert(string.IsNullOrWhiteSpace(function()));
}
public static void AssertIsNotNullOrEmpty(Func<string> function)
{
Trace.Assert(!string.IsNullOrEmpty(function()));
}
public static void AssertIsNotNullOrWhitespace(Func<string> function)
{
Trace.Assert(!string.IsNullOrWhiteSpace(function()));
}
public static void AssertEquals<U>(Func<U> function, U value)
{
Trace.Assert(object.Equals(function(), value));
}
public static void AssertNotEquals<U>(Func<U> function, U value)
{
Trace.Assert(!object.Equals(function(), value));
}
public static void AssertDefault<U>(Func<U> function)
{
Trace.Assert(object.Equals(function(), default(U)));
}
public static void AssertNonDefault<U>(Func<U> function)
{
Trace.Assert(!object.Equals(function(), default(U)));
}
public static void AssertNotNull<U>(Func<U> function)
{
Trace.Assert(!object.Equals(function(), default(U)));
}
public static void AssertNull<U>(Func<U> function)
{
Trace.Assert(object.Equals(function(), default(U)));
}
public static void AssertPositive(Func<int> function)
{
Trace.Assert(function() > 0);
}
public static void AssertPositive(Func<long> function)
{
Trace.Assert(function() > 0);
}
public static void AssertNegative(Func<int> function)
{
Trace.Assert(function() < 0);
}
public static void AssertNegative(Func<long> function)
{
Trace.Assert(function() < 0);
}
public static void AssertEqualsZero(Func<int> function)
{
Trace.Assert(function() == 0);
}
public static void AssertEqualsZero(Func<long> function)
{
Trace.Assert(function() == 0);
}
public static void AssertNotEqualsZero(Func<int> function)
{
Trace.Assert(function() != 0);
}
public static void AssertNotEqualsZero(Func<long> function)
{
Trace.Assert(function() != 0);
}
public static void AssertGreaterThan(Func<int> function, int value)
{
Trace.Assert(function() > value);
}
public static void AssertGreaterThan(Func<long> function, long value)
{
Trace.Assert(function() > value);
}
public static void AssertLessThan(Func<int> function, int value)
{
Trace.Assert(function() < value);
}
public static void AssertLessThan(Func<long> function, long value)
{
Trace.Assert(function() < value);
}
public static void AssertGreaterOrEqualsThan(Func<int> function, int value)
{
Trace.Assert(function() >= value);
}
public static void AssertGreaterOrEqualsThan(Func<long> function, long value)
{
Trace.Assert(function() >= value);
}
public static void AssertLessOrEqualsThan(Func<int> function, int value)
{
Trace.Assert(function() <= value);
}
public static void AssertLessOrEqualsThan(Func<long> function, long value)
{
Trace.Assert(function() <= value);
}
public static void AssertGreaterOrEqualsZero(Func<int> function)
{
Trace.Assert(function() >= 0);
}
public static void AssertGreaterOrEqualsZero(Func<long> function, long value)
{
Trace.Assert(function() >= 0);
}
public static void AssertLessOrEqualsZero<T>(Func<int> function)
{
Trace.Assert(function() <= 0);
}
public static void AssertLessOrEqualsZero(Func<long> function)
{
Trace.Assert(function() <= 0);
}
}

0
ответ дан 17 октября 2011 в 10:10 Источник Поделиться