Какие-нибудь альтернативные решения общих атрибутов типа? - PullRequest
1 голос
/ 30 сентября 2010

Поскольку мы не можем использовать атрибуты универсального типа , есть ли альтернативные решения?Может быть, полезно обсудить пример:

public abstract class ErrorHandler { }
public class AccessHandler : ErrorHandler { }
public class ConnectionHandler : ErrorHandler { }
public class OtherHandler : ErrorHandler { }

public class CoHandler<T> : Attribute where T : ErrorHandler
{
    public T GetHandler()
    {
        return default(T);  // just an example
    }

}
public enum Errors
{
    [CoHandler<AccessHandler>()]
    Access,
    [CoHandler<ConnectionHandler>()]
    Connection,
    [CoHandler<OtherHandler>()]
    Other
}

Ответы [ 2 ]

4 голосов
/ 30 сентября 2010

Хорошо, вы можете принять аргумент типа или имени типа в конструкторе атрибутов. Например

[CoHandler(typeof(AccessHandler))]

или

[CoHandler("[Fully or partially qualified type name]")]

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

Кстати, return default(T); всегда будет возвращать ноль, я надеюсь, это просто для иллюстрации. Вот пример того, как вы можете использовать аргумент типа:

public class CoHandler : Attribute
{
    private Type _Type;

    public CoHandler(Type type)
    {
       _Type = type;

       // Use reflection to validate type argument to see if it has 
       // inherited from ErrorHandler  and check if its has parameterless 
       // constructor
    }

    public ErrorHandler GetHandler()
    {
        return (ErrorHandler)Activator.CreateInstance(_Type);
    }

}
0 голосов
/ 03 октября 2010

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

Вы можете проверить реализацию интерфейса с как , а также можете написать методы расширения для интерфейса.

Вы также можете реализовать методы в классах Errors, предоставляя больший диапазон, чем простые старые перечисления.

{
    Errors error = Errors.Access;
    var handler = error.GetHandler();   
}

public abstract class ErrorHandler { }
public class AccessHandler : ErrorHandler { }
public class ConnectionHandler : ErrorHandler { }
public class OtherHandler : ErrorHandler { }

public interface CoHandler<T>
    where T : ErrorHandler
{
    T GetHandler();
}

public abstract class Errors
{
    public static Errors Access = new AccessError();
    public static Errors Connection = new ConnectionError();

    public abstract ErrorHandler GetHandler();

    private class AccessError : Errors, CoHandler<AccessHandler>
    {
        public override ErrorHandler GetHandler()
        {
            return new AccessHandler();
        }

        AccessHandler CoHandler<AccessHandler>.GetHandler()
        {
            return new AccessHandler();
        }
    }

    private class ConnectionError : Errors, CoHandler<ConnectionHandler>
    {
        public override ErrorHandler GetHandler()
        {
            return new ConnectionHandler();
        }

        ConnectionHandler CoHandler<ConnectionHandler>.GetHandler()
        {
            return new ConnectionHandler();
        }
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...