Skip to main content
Rollback to Revision 1
Source Link
sarin
  • 250
  • 1
  • 2
  • 8

I have have attempted to use generics and constraints to create functions that retrieve and save data from a number of similar objects. Each of these objects describe their own properties. When I use these methods for a particular Type I don't understand why I have to specify new()new() in the constraint and also create a new version of the type in order to access its underlying properties to assist me. I'm sure there is a better way, but my knowledge in this area is a little lacking.

There are a number of objects that inherit from RawDataAggregatedItemRawDataAggregatedItem.

RawDataAggregatedItem RawDataAggregatedItem has itsit's own interface:

 
public RawDataAggregatedItems&lt;T&gt;RawDataAggregatedItems<T> GetRawDataAggregated&lt;T&gt;GetRawDataAggregated<T>(int? id) where T : IRawDataAggregatedItem, <strong><em>new()</em></strong>new()
    {
        try
        {
        <strong><em>var itemType = new T();</em></strong>var itemType = new T();
            using (var cn = Connection())
            {
                var cmd = new SqlCommand(<strong><em>itemType.GetStoredProcedureName</em></strong>itemType.GetStoredProcedureName, cn) { CommandTimeout = _commandTimeout, CommandType = CommandType.StoredProcedure };
                cmd.Parameters.Add(new SqlParameter("@periodId""@periodId", SqlDbType.Int)).Value = id;
                return new RawDataAggregatedItems&lt;T&gt;RawDataAggregatedItems<T>(cmd.ExecuteReader());
            }
        }
        catch (Exception ex)
        {
            throw new Exception("Error"Error fetching aggregated rawdata list."", ex);
        }
    }

public void UpdateRawDataAggregated(RawDataAggregatedItem itemToUpdate)
    {
        try
        {
            using (var cn = Connection())
            {
                var cmd = new SqlCommand(<strong><em>itemToUpdate.UpdateStoredProcedureName</em></strong>itemToUpdate.UpdateStoredProcedureName, cn) { CommandTimeout = _commandTimeout, CommandType = CommandType.StoredProcedure };
                cmd.Parameters.Add(new SqlParameter("@projectid""@projectid", SqlDbType.VarChar)).Value = ((IRawDataAggregatedItem)itemToUpdate).ID;
                cmd.Parameters.Add(new SqlParameter("@is_flagged""@is_flagged", SqlDbType.Bit)).Value = ((IRawDataAggregatedItem)itemToUpdate).isFlaggedForReview;
                cmd.Parameters.Add(new SqlParameter("@is_reviewed""@is_reviewed", SqlDbType.Bit)).Value = ((IRawDataAggregatedItem)itemToUpdate).isReviewed;
                cmd.ExecuteReader();
            }
        }
        catch (Exception ex)
        {
            throw new Exception("Error"Error updating aggregated rawdata item."", ex);
        }
    }

ItIf feels a bit wrong to

  1. Supplysupply new() in the GetRawDataAggregated constraint but the compiler is forcing me to.
  2. New-ing up a Type T (var itemType = new T()) in order to get to T.Property.

CouldPlease could you please suggest a better way of doing this?

I have have attempted to use generics and constraints to create functions that retrieve and save data from a number of similar objects. Each of these objects describe their own properties. When I use these methods for a particular Type I don't understand why I have to specify new() in the constraint and also create a new version of the type in order to access its underlying properties to assist me. I'm sure there is a better way, but my knowledge in this area is a little lacking.

There are a number of objects that inherit from RawDataAggregatedItem.

RawDataAggregatedItem has its own interface:

public RawDataAggregatedItems&lt;T&gt; GetRawDataAggregated&lt;T&gt;(int? id) where T : IRawDataAggregatedItem, <strong><em>new()</em></strong>
{
    try
    {
        <strong><em>var itemType = new T();</em></strong>
        using (var cn = Connection())
        {
            var cmd = new SqlCommand(<strong><em>itemType.GetStoredProcedureName</em></strong>, cn) { CommandTimeout = _commandTimeout, CommandType = CommandType.StoredProcedure };
            cmd.Parameters.Add(new SqlParameter("@periodId", SqlDbType.Int)).Value = id;
            return new RawDataAggregatedItems&lt;T&gt;(cmd.ExecuteReader());
        }
    }
    catch (Exception ex)
    {
        throw new Exception("Error fetching aggregated rawdata list.", ex);
    }
}

public void UpdateRawDataAggregated(RawDataAggregatedItem itemToUpdate)
{
    try
    {
        using (var cn = Connection())
        {
            var cmd = new SqlCommand(<strong><em>itemToUpdate.UpdateStoredProcedureName</em></strong>, cn) { CommandTimeout = _commandTimeout, CommandType = CommandType.StoredProcedure };
            cmd.Parameters.Add(new SqlParameter("@projectid", SqlDbType.VarChar)).Value = ((IRawDataAggregatedItem)itemToUpdate).ID;
            cmd.Parameters.Add(new SqlParameter("@is_flagged", SqlDbType.Bit)).Value = ((IRawDataAggregatedItem)itemToUpdate).isFlaggedForReview;
            cmd.Parameters.Add(new SqlParameter("@is_reviewed", SqlDbType.Bit)).Value = ((IRawDataAggregatedItem)itemToUpdate).isReviewed;
            cmd.ExecuteReader();
        }
    }
    catch (Exception ex)
    {
        throw new Exception("Error updating aggregated rawdata item.", ex);
    }
}

It feels a bit wrong to

  1. Supply new() in the GetRawDataAggregated constraint but the compiler is forcing me to.
  2. New-ing up a Type T (var itemType = new T()) in order to get to T.Property

Could you please suggest a better way of doing this?

I have have attempted to use generics and constraints to create functions that retrieve and save data from a number of similar objects. Each of these objects describe their own properties. When I use these methods for a particular Type I don't understand why I have to specify new() in the constraint and also create a new version of the type in order to access its underlying properties to assist me. I'm sure there is a better way, but my knowledge in this area is a little lacking.

There are a number of objects that inherit from RawDataAggregatedItem.

RawDataAggregatedItem has it's own interface:

 
public RawDataAggregatedItems<T> GetRawDataAggregated<T>(int? id) where T : IRawDataAggregatedItem, new()
    {
        try
        {
            var itemType = new T();
            using (var cn = Connection())
            {
                var cmd = new SqlCommand(itemType.GetStoredProcedureName, cn) { CommandTimeout = _commandTimeout, CommandType = CommandType.StoredProcedure };
                cmd.Parameters.Add(new SqlParameter("@periodId", SqlDbType.Int)).Value = id;
                return new RawDataAggregatedItems<T>(cmd.ExecuteReader());
            }
        }
        catch (Exception ex)
        {
            throw new Exception("Error fetching aggregated rawdata list.", ex);
        }
    }

public void UpdateRawDataAggregated(RawDataAggregatedItem itemToUpdate)
    {
        try
        {
            using (var cn = Connection())
            {
                var cmd = new SqlCommand(itemToUpdate.UpdateStoredProcedureName, cn) { CommandTimeout = _commandTimeout, CommandType = CommandType.StoredProcedure };
                cmd.Parameters.Add(new SqlParameter("@projectid", SqlDbType.VarChar)).Value = ((IRawDataAggregatedItem)itemToUpdate).ID;
                cmd.Parameters.Add(new SqlParameter("@is_flagged", SqlDbType.Bit)).Value = ((IRawDataAggregatedItem)itemToUpdate).isFlaggedForReview;
                cmd.Parameters.Add(new SqlParameter("@is_reviewed", SqlDbType.Bit)).Value = ((IRawDataAggregatedItem)itemToUpdate).isReviewed;
                cmd.ExecuteReader();
            }
        }
        catch (Exception ex)
        {
            throw new Exception("Error updating aggregated rawdata item.", ex);
        }
    }

If feels a bit wrong to

  1. supply new() in the GetRawDataAggregated constraint but the compiler is forcing me to.
  2. New-ing up a Type T (var itemType = new T()) in order to get to T.Property.

Please could you suggest a better way of doing this?

deleted 17 characters in body
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237

I have have attempted to use generics and constraints to create functions that retrieve and save data from a number of similar objects. Each of these objects describe their own properties. When I use these methods for a particular Type I don't understand why I have to specify new()new() in the constraint and also create a new version of the type in order to access its underlying properties to assist me. I'm sure there is a better way, but my knowledge in this area is a little lacking.

There are a number of objects that inherit from RawDataAggregatedItemRawDataAggregatedItem.

RawDataAggregatedItemRawDataAggregatedItem has it'sits own interface:


 public RawDataAggregatedItems<T>RawDataAggregatedItems&lt;T&gt; GetRawDataAggregated<T>GetRawDataAggregated&lt;T&gt;(int? id) where T : IRawDataAggregatedItem, new()<strong><em>new()</em></strong>
    {
        try
        {
        <strong><em>var itemType = new var itemType = new T();T();</em></strong>
            using (var cn = Connection())
            {
                var cmd = new SqlCommand(itemType.GetStoredProcedureName<strong><em>itemType.GetStoredProcedureName</em></strong>, cn) { CommandTimeout = _commandTimeout, CommandType = CommandType.StoredProcedure };
                cmd.Parameters.Add(new SqlParameter("@periodId""@periodId", SqlDbType.Int)).Value = id;
                return new RawDataAggregatedItems<T>RawDataAggregatedItems&lt;T&gt;(cmd.ExecuteReader());
            }
        }
        catch (Exception ex)
        {
            throw new Exception("Error"Error fetching aggregated rawdata list."", ex);
        }
    }

public void UpdateRawDataAggregated(RawDataAggregatedItem itemToUpdate)
    {
        try
        {
            using (var cn = Connection())
            {
                var cmd = new SqlCommand(itemToUpdate.UpdateStoredProcedureName<strong><em>itemToUpdate.UpdateStoredProcedureName</em></strong>, cn) { CommandTimeout = _commandTimeout, CommandType = CommandType.StoredProcedure };
                cmd.Parameters.Add(new SqlParameter("@projectid""@projectid", SqlDbType.VarChar)).Value = ((IRawDataAggregatedItem)itemToUpdate).ID;
                cmd.Parameters.Add(new SqlParameter("@is_flagged""@is_flagged", SqlDbType.Bit)).Value = ((IRawDataAggregatedItem)itemToUpdate).isFlaggedForReview;
                cmd.Parameters.Add(new SqlParameter("@is_reviewed""@is_reviewed", SqlDbType.Bit)).Value = ((IRawDataAggregatedItem)itemToUpdate).isReviewed;
                cmd.ExecuteReader();
            }
        }
        catch (Exception ex)
        {
            throw new Exception("Error"Error updating aggregated rawdata item."", ex);
        }
    }

IfIt feels a bit wrong to

  1. supplySupply new() in the GetRawDataAggregated constraint but the compiler is forcing me to.
  2. New-ing up a Type T (var itemType = new T()) in order to get to T.Property.

Please couldCould you please suggest a better way of doing this?

I have have attempted to use generics and constraints to create functions that retrieve and save data from a number of similar objects. Each of these objects describe their own properties. When I use these methods for a particular Type I don't understand why I have to specify new() in the constraint and also create a new version of the type in order to access its underlying properties to assist me. I'm sure there is a better way, but my knowledge in this area is a little lacking.

There are a number of objects that inherit from RawDataAggregatedItem.

RawDataAggregatedItem has it's own interface:


 public RawDataAggregatedItems<T> GetRawDataAggregated<T>(int? id) where T : IRawDataAggregatedItem, new()
    {
        try
        {
            var itemType = new T();
            using (var cn = Connection())
            {
                var cmd = new SqlCommand(itemType.GetStoredProcedureName, cn) { CommandTimeout = _commandTimeout, CommandType = CommandType.StoredProcedure };
                cmd.Parameters.Add(new SqlParameter("@periodId", SqlDbType.Int)).Value = id;
                return new RawDataAggregatedItems<T>(cmd.ExecuteReader());
            }
        }
        catch (Exception ex)
        {
            throw new Exception("Error fetching aggregated rawdata list.", ex);
        }
    }

public void UpdateRawDataAggregated(RawDataAggregatedItem itemToUpdate)
    {
        try
        {
            using (var cn = Connection())
            {
                var cmd = new SqlCommand(itemToUpdate.UpdateStoredProcedureName, cn) { CommandTimeout = _commandTimeout, CommandType = CommandType.StoredProcedure };
                cmd.Parameters.Add(new SqlParameter("@projectid", SqlDbType.VarChar)).Value = ((IRawDataAggregatedItem)itemToUpdate).ID;
                cmd.Parameters.Add(new SqlParameter("@is_flagged", SqlDbType.Bit)).Value = ((IRawDataAggregatedItem)itemToUpdate).isFlaggedForReview;
                cmd.Parameters.Add(new SqlParameter("@is_reviewed", SqlDbType.Bit)).Value = ((IRawDataAggregatedItem)itemToUpdate).isReviewed;
                cmd.ExecuteReader();
            }
        }
        catch (Exception ex)
        {
            throw new Exception("Error updating aggregated rawdata item.", ex);
        }
    }

If feels a bit wrong to

  1. supply new() in the GetRawDataAggregated constraint but the compiler is forcing me to.
  2. New-ing up a Type T (var itemType = new T()) in order to get to T.Property.

Please could you suggest a better way of doing this?

I have have attempted to use generics and constraints to create functions that retrieve and save data from a number of similar objects. Each of these objects describe their own properties. When I use these methods for a particular Type I don't understand why I have to specify new() in the constraint and also create a new version of the type in order to access its underlying properties to assist me. I'm sure there is a better way, but my knowledge in this area is a little lacking.

There are a number of objects that inherit from RawDataAggregatedItem.

RawDataAggregatedItem has its own interface:

public RawDataAggregatedItems&lt;T&gt; GetRawDataAggregated&lt;T&gt;(int? id) where T : IRawDataAggregatedItem, <strong><em>new()</em></strong>
{
    try
    {
        <strong><em>var itemType = new T();</em></strong>
        using (var cn = Connection())
        {
            var cmd = new SqlCommand(<strong><em>itemType.GetStoredProcedureName</em></strong>, cn) { CommandTimeout = _commandTimeout, CommandType = CommandType.StoredProcedure };
            cmd.Parameters.Add(new SqlParameter("@periodId", SqlDbType.Int)).Value = id;
            return new RawDataAggregatedItems&lt;T&gt;(cmd.ExecuteReader());
        }
    }
    catch (Exception ex)
    {
        throw new Exception("Error fetching aggregated rawdata list.", ex);
    }
}

public void UpdateRawDataAggregated(RawDataAggregatedItem itemToUpdate)
{
    try
    {
        using (var cn = Connection())
        {
            var cmd = new SqlCommand(<strong><em>itemToUpdate.UpdateStoredProcedureName</em></strong>, cn) { CommandTimeout = _commandTimeout, CommandType = CommandType.StoredProcedure };
            cmd.Parameters.Add(new SqlParameter("@projectid", SqlDbType.VarChar)).Value = ((IRawDataAggregatedItem)itemToUpdate).ID;
            cmd.Parameters.Add(new SqlParameter("@is_flagged", SqlDbType.Bit)).Value = ((IRawDataAggregatedItem)itemToUpdate).isFlaggedForReview;
            cmd.Parameters.Add(new SqlParameter("@is_reviewed", SqlDbType.Bit)).Value = ((IRawDataAggregatedItem)itemToUpdate).isReviewed;
            cmd.ExecuteReader();
        }
    }
    catch (Exception ex)
    {
        throw new Exception("Error updating aggregated rawdata item.", ex);
    }
}

It feels a bit wrong to

  1. Supply new() in the GetRawDataAggregated constraint but the compiler is forcing me to.
  2. New-ing up a Type T (var itemType = new T()) in order to get to T.Property

Could you please suggest a better way of doing this?

Source Link
sarin
  • 250
  • 1
  • 2
  • 8

Generic Constraints and new()

I have have attempted to use generics and constraints to create functions that retrieve and save data from a number of similar objects. Each of these objects describe their own properties. When I use these methods for a particular Type I don't understand why I have to specify new() in the constraint and also create a new version of the type in order to access its underlying properties to assist me. I'm sure there is a better way, but my knowledge in this area is a little lacking.

There are a number of objects that inherit from RawDataAggregatedItem.

public class Project : RawDataAggregatedItem
{
    public override string IdColumnName
    {
        get { return "project_id"; }
    }

    public override string DescriptionColumnName
    {
        get { return "project_description"; }
    }

    public override string GetStoredProcedureName
    {
        get { return "R_projects_sp"; }
    }
}

...

public class Category : RawDataAggregatedItem
{
    public override string IdColumnName
    {
        get { return "asset_category"; }
    }

    public override string GetStoredProcedureName
    {
        get { return "R_asset_category_sp"; }
    }
}

RawDataAggregatedItem has it's own interface:

public interface IRawDataAggregatedItem
{
    string IdColumnName { get; }
    string DescriptionColumnName { get; }
}

public abstract class RawDataAggregatedItem : IRawDataAggregatedItem
{

    public abstract string IdColumnName { get; }
    public virtual string DescriptionColumnName
    {
        get { return string.Empty; }
    }
    public abstract string GetStoredProcedureName { get; }
}

I've created functions that get and save data to the database using generics expecting these different object types:


public RawDataAggregatedItems<T> GetRawDataAggregated<T>(int? id) where T : IRawDataAggregatedItem, new()
    {
        try
        {
            var itemType = new T();
            using (var cn = Connection())
            {
                var cmd = new SqlCommand(itemType.GetStoredProcedureName, cn) { CommandTimeout = _commandTimeout, CommandType = CommandType.StoredProcedure };
                cmd.Parameters.Add(new SqlParameter("@periodId", SqlDbType.Int)).Value = id;
                return new RawDataAggregatedItems<T>(cmd.ExecuteReader());
            }
        }
        catch (Exception ex)
        {
            throw new Exception("Error fetching aggregated rawdata list.", ex);
        }
    }

public void UpdateRawDataAggregated(RawDataAggregatedItem itemToUpdate)
    {
        try
        {
            using (var cn = Connection())
            {
                var cmd = new SqlCommand(itemToUpdate.UpdateStoredProcedureName, cn) { CommandTimeout = _commandTimeout, CommandType = CommandType.StoredProcedure };
                cmd.Parameters.Add(new SqlParameter("@projectid", SqlDbType.VarChar)).Value = ((IRawDataAggregatedItem)itemToUpdate).ID;
                cmd.Parameters.Add(new SqlParameter("@is_flagged", SqlDbType.Bit)).Value = ((IRawDataAggregatedItem)itemToUpdate).isFlaggedForReview;
                cmd.Parameters.Add(new SqlParameter("@is_reviewed", SqlDbType.Bit)).Value = ((IRawDataAggregatedItem)itemToUpdate).isReviewed;
                cmd.ExecuteReader();
            }
        }
        catch (Exception ex)
        {
            throw new Exception("Error updating aggregated rawdata item.", ex);
        }
    }

If feels a bit wrong to

  1. supply new() in the GetRawDataAggregated constraint but the compiler is forcing me to.
  2. New-ing up a Type T (var itemType = new T()) in order to get to T.Property.

Please could you suggest a better way of doing this?