在泛型中使用必需的构造函数继承类

基思·巴罗斯(Keith Barrows)

我的解决方案中有几个使用以下模式的对象:

#region Repositories
private RepositoryAccount _account;
private RepositoryInquiry _inquiry;
private RepositoryLoan _loan;

public RepositoryAccount Account { get { return _account ?? (_account = new RepositoryAccount(this)); } }
public RepositoryInquiry Inquiry { get { return _inquiry ?? (_inquiry = new RepositoryInquiry(this)); } }
public RepositoryLoan Loan { get { return _loan ?? (_loan = new RepositoryLoan(this)); } }
#endregion

我创建了一个通用类,试图使该属性处理得更干净一些,但遇到了麻烦。属性类如下所示:

public class Property<T> where T : class, new()
{
    private T _value;

    public T Value
    {
        get { return _value ?? (_value = new T()); }
        set
        {
            // insert desired logic here
            _value = value;
        }
    }

    public static implicit operator T(Property<T> value)
    {
        return value.Value;
    }

    public static implicit operator Property<T>(T value)
    {
        return new Property<T> { Value = value };
    }
}

我将属性(用支持对象)替换为新的通用属性,例如:

public Property<RepositoryAccount> Account { get; set; }
public Property<RepositoryInquiry> Inquiry { get; set; }
public Property<RepositoryLoan> Loan { get; set; }

但是,如果您在原始的公共获取器中注意到,则需要用另一个对象实例化每个对象:这是必需的,并且这些存储库对象没有无参数的构造函数。

有什么建议?


整个对象看起来像:

public class UnitOfWorkSymitar : IUnitOfWork
{
    #region Properties
    internal IPHostEntry IpHostInfo;
    internal IPAddress IpAddress;
    internal IPEndPoint RemotEndPoint;
    internal System.Net.Sockets.Socket Sender;
    internal byte[] Bytes = new byte[1024];
    internal bool IsAllowedToRun = false;
    internal string SymServerIp;
    internal int SymPort;
    public string State { get; set; }
    #endregion

    #region Constructor
    public UnitOfWorkSymitar() { OpenSymitarConnection(); }
    protected UnitOfWorkSymitar(string serverIp, int? port) { OpenSymitarConnection(serverIp, port); }
    #endregion

    #region Implement IUnitOfWork
    public void Commit() { /* No commit on this socket connection */ }
    public void Rollback() { /* No rollback on this socket connection */ }
    #endregion

    #region Implement IDisposable
    /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
    public void Dispose()
    {
        CloseSymitarConnection();
    }
    #endregion

    #region Private Helpers
    /// <summary>
    /// Connect to a remote device.
    /// </summary>
    /// <returns>Success/failure message</returns>
    private string OpenSymitarConnection(string serverIp = null, int? port = null)
    {
        var config = ConfigInfoSymitar.Instance;
        SymServerIp = serverIp ?? config.SymServerIp;
        SymPort = port ?? config.SymPort;
        try
        {
            // Establish the remote endpoint for the socket.
            //IpHostInfo = Dns.GetHostEntry(SymServerIp);
            //IpAddress = IpHostInfo.AddressList[0];

            IpAddress = Dns.GetHostAddresses(SymServerIp)[0];

            RemotEndPoint = new IPEndPoint(IpAddress, SymPort);
            // Create a TCP/IP socket.
            Sender = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            // Connect the socket to the remote endpoint. Catch any errors.
            Sender.Connect(RemotEndPoint);
        }
        catch (Exception ex)
        {
            State = DetermineError(ex);
            return State;
            //throw;
        }

        IsAllowedToRun = true;
        State = "Success";
        return State;
    }
    /// <summary>
    /// Setup and send the request
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    public string SendMessage(string request)
    {
        try
        {
            // Encode the data string into a byte array and add the carriage return for SymConnect.
            var msg = Encoding.ASCII.GetBytes(request);
            if(!request.EndsWith("\n"))
                msg = Encoding.ASCII.GetBytes(request + "\n");
            // Send the data through the socket.
            var bytesSent = Sender.Send(msg);
            // Receive the response from the remote device.
            var bytesRec = Sender.Receive(Bytes);
            var response = Encoding.ASCII.GetString(Bytes, 0, bytesRec);
            response = response.Replace("\n", "");
            return response;
        }
        catch (Exception ex)
        {
            return DetermineError(ex);
        }
    }
    /// <summary>
    /// Close the connection to a remote device.
    /// </summary>
    /// <returns></returns>
    private string CloseSymitarConnection()
    {
        try
        {
            // Release the socket.
            Sender.Shutdown(SocketShutdown.Both);
            Sender.Close();
        }
        catch (Exception ex)
        {
            return DetermineError(ex);
        }
        finally
        {
            IsAllowedToRun = false;
        }
        return "Success!";
    }
    /// <summary>
    /// Determine if this is an Arguments, Socket or some other exception
    /// </summary>
    /// <param name="ex">The exception to be checked</param>
    /// <returns>String message</returns>
    private static string DetermineError(Exception ex)
    {
        if (ex.GetType() == typeof(ArgumentNullException))
            return "Missing Arguments: " + Environment.NewLine + ex.GetFullMessage();
        if (ex.GetType() == typeof(SocketException))
            return "Socket Error: " + Environment.NewLine + ex.GetFullMessage();
        return "Unexpected Error: " + Environment.NewLine + ex.GetFullMessage();
    }
    #endregion

    #region Symitar Samples
    private static string ExecSymConnectRequest(string symServerIP, int symPort, string request)
    {
        // Data buffer for incoming data.
        var bytes = new byte[1024];
        // Connect to a remote device.
        try
        {
            // Establish the remote endpoint for the socket.
            // This example uses port 11000 on the local computer.
            var ipHostInfo = Dns.GetHostEntry(symServerIP);
            var ipAddress = ipHostInfo.AddressList[0];
            var remoteEP = new IPEndPoint(ipAddress, symPort);
            // Create a TCP/IP socket.
            var sender = new System.Net.Sockets.Socket(AddressFamily.InterNetwork
                                  , SocketType.Stream
                                  , ProtocolType.Tcp);

            // Connect the socket to the remote endpoint. Catch any errors.
            try
            {
                sender.Connect(remoteEP);
                // Encode the data string into a byte array and add the carriage return for SymConnect.
                var msg = Encoding.ASCII.GetBytes(request + "\n");
                // Send the data through the socket.
                var bytesSent = sender.Send(msg);
                // Receive the response from the remote device.
                var bytesRec = sender.Receive(bytes);
                var response = Encoding.ASCII.GetString(bytes, 0, bytesRec);
                // Release the socket.
                sender.Shutdown(SocketShutdown.Both);
                sender.Close();
                response.Replace("\n", "");
                return response;
            }
            catch (ArgumentNullException ane)
            {
                return "Missing Arguments: " + ane.Message;
            }
            catch (SocketException se)
            {
                return "Socket Error: " + se.Message;
            }
            catch (Exception e)
            {
                return "Unexpected Error: " + e.Message;
            }
        }
        catch (Exception e)
        {
            return e.Message;
        }
    }
    #endregion

    #region Repositories
    private RepositoryAccount _account;
    private RepositoryInquiry _inquiry;
    private RepositoryLoan _loan;

    public RepositoryAccount Account { get { return _account ?? (_account = new RepositoryAccount(this)); } }
    public RepositoryInquiry Inquiry { get { return _inquiry ?? (_inquiry = new RepositoryInquiry(this)); } }
    public RepositoryLoan Loan { get { return _loan ?? (_loan = new RepositoryLoan(this)); } }
    #endregion
}
瑞安·CS

可以尝试以下方法:

class Program {
    Property<string> Foo = new Property<string>(() => "FOO!");
}

public class Property<T> where T : class {
    private Lazy<T> instance;

    public Property(Func<T> generator) {
        instance = new Lazy<T>(generator);
    }

    public T Value {
        get { return instance.Value; }
    }

    public static implicit operator T(Property<T> value) {
        return value.Value;
    }

    public static implicit operator Property<T>(T value) {
        return new Property<T>(() => value);
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在类构造函数中使用泛型

继承需要构造函数的泛型类型的抽象类

继承类中的泛型和构造函数

泛型类的泛型构造函数

如何在函数调用中使用Typescript泛型类构造函数作为参数

如何为从具有泛型的抽象类继承的类创建构造函数?

使用泛型在抽象类中调用构造函数

在Haskell中使用泛型列出构造函数名称

在Haskell中使用泛型获取构造函数索引

具有构造函数中泛型类型的Java类的Scala继承

在不继承C#的情况下为泛型类创建具体的构造函数

在继承的类构造函数中使用隐藏成员

如何建立一个类和构造函数泛型以使用泛型方法?

如何使用泛型类型数组和泛型类型类作为构造函数中的参数?

具有泛型构造函数的泛型类?

继承泛型类

使用类泛型构造的子类型

使用泛型类型的Java构造函数

构造函数作为参数:推断类的泛型为函数

是否有可能在引入其他泛型类型的泛型类上使用构造函数?

Kotlin:使用继承或泛型将函数重用于不同的类

使用约定在MEF 2中使用默认构造函数和开放泛型

在泛型类中使用 initialCapacity 创建泛型 ArrayList

在泛型类中使用泛型接口

当父类在 C++ 中没有默认构造函数时,如何在继承的类中使用构造函数?

使用继承的类时处理构造函数

在Java中,为什么不能在泛型类上使用构造函数?

使用构造函数的泛型和/或对象返回超类或子类

使用不同的构造函数参数实例化泛型类