C # Generics and Casting Issue

I am having trouble sending an object to a shared IList. I have a group of applications to try to get around this, but there must be a better way to do this.

This is my current method:

string values;

if (colFilter.Value is IList<int>)
{
    values = BuildClause((IList<int>)colFilter.Value, prefix);
}
else if (colFilter.Value is IList<string>)
{
    values = BuildClause((IList<string>)colFilter.Value, prefix);
}
else if (colFilter.Value is IList<DateTime>)
{
    values = BuildClause((IList<DateTime>)colFilter.Value, prefix);
}
else if (...) //etc.

I want to do the following:

values = BuildClause((IList<colFilter.ColumnType>)colFilter.Value, prefix);

or

values = BuildClause((IList<typeof(colFilter.ColumnType)>)colFilter.Value, prefix);

or

values = BuildClause((IList<colFilter.ColumnType.GetType()>)colFilter.Value, prefix);

Each of them creates this compiler error: The type or namespace name "colFilter" could not be found (did you specify a usage directive or assembly reference?)

In my example, colFilter.ColumnType is int, string, datetime, etc. I am not sure why this is not working.

Any ideas?

EDIT: this is C # 2.0

EDIT No. 2

Here is the BuildClause method (I have overloads for each type):

private static string BuildClause(IList<int> inClause, string strPrefix)
{
    return BuildClause(inClause, strPrefix, false);
}

private static string BuildClause(IList<String> inClause, string strPrefix)
{
    return BuildClause(inClause, strPrefix, true);
}

private static string BuildClause(IList<DateTime> inClause, string strPrefix)
{
    return BuildClause(inClause, strPrefix, true);
}
//.. etc for all types

private static string BuildClause<T>(IList<T> inClause, string strPrefix, bool addSingleQuotes)
    {
        StringBuilder sb = new StringBuilder();

        //Check to make sure inclause has objects
        if (inClause.Count > 0)
        {
            sb.Append(strPrefix);
            sb.Append(" IN(");

            for (int i = 0; i < inClause.Count; i++)
            {
                if (addSingleQuotes)
                {
                    sb.AppendFormat("'{0}'", inClause[i].ToString().Replace("'", "''"));
                }
                else
                {
                    sb.Append(inClause[i].ToString());
                }

                if (i != inClause.Count - 1)
                {
                    sb.Append(",");
                }
            }

            sb.Append(") ");
        }
        else
        {
            throw new Exception("Item count for In() Clause must be greater than 0.");
        }

        return sb.ToString();
    }
+3
source share
6 answers

: , . , ; generics .

BuildClause , - ( , - , - , ), -, , - " - , , " ( "switch-on-type" ).

, "-" . , StringColFilter : ColFilter<string> IntColFilter : ColFilter<int>, ColFilter<T> BuildClause ( , BuildClause ). ColFilter, " " . , , , , ColFilters .

:

abstract class ColFilter<T> 
{
    abstract bool AddSingleQuotes { get; }
    List<T> Values { get; }
}

class IntColFilter<T>
{
    override bool AddSingleQuotes { get { return false; } }    
}

class StringColFilter<T>
{
    override bool AddSingleQuotes { get { return true; } }
}

class SomeOtherClass 
{
    public static string BuildClause<T>(string prefix, ColFilter<T> filter)
    {
        return BuildClause(prefix, filter.Values, filter.AddSingleQuotes);
    }

    public static string BuildClause<T>(string prefix, IList<T> values, bool addSingleQuotes) 
    {
        // use your existing implementation, since here we don't care about types anymore -- 
        // all we do is call ToString() on them.
        // in fact, we don't need this method to be generic at all!
    }
}

, , ColFilter , :)

, , -, SQL-, , , , , , , .

+5

BuildClause().

, BuildClause() IList, . , .ToString() .

+2

# 3.0, , , (int # 2.0 ). BuildClause , , ():

public IList<T> BuildClause<T>(IList<T> value, object prefix)
{
    Type type = typeof(T);
    if (type == typeof(string))
    {
        // handle string
    }
    else if (type == typeof(int))
    {
        // handle int
    }
    // ...
}

public class ColumnFilter<T>:
    where T: struct
{
    public IList<T> Value { get; set; }
}

var colFilter = new ColumnFilter<string>
{
    Value = new { "string 1", "string 2", "string 3" }
}

IList<string> values = BuildClause(colFilter.Value, prefix);

ColumnType ColumnFilter. , BuildClause, , typeof (T).

+2

- .

.

.

- sql - .

+2

. . , ? ?

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1 {

  class Foo<T> : List<T> {
  }

  class Program {
    static void Main(string[] args) {

    var a = new Foo<int>();
    a.Add(1);
    var b = new Foo<string>();
    b.Add("foo");
    Console.WriteLine(BuildClause(a, "foo", true));
    Console.WriteLine(BuildClause(b, "foo", true));

    }

    private static string BuildClause<T>(IList<T> inClause, string strPrefix, bool addSingleQuotes) {
      StringBuilder sb = new StringBuilder();

      //Check to make sure inclause has objects
      if (inClause.Count == 0) 
        throw new Exception("Item count for In() Clause must be greater than 0.");
      sb.Append(strPrefix).Append(" IN(");
      foreach (var Clause in inClause) {
        if (addSingleQuotes) 
          sb.AppendFormat("'{0}'", Clause.ToString().Replace("'", "''"));
        else
          sb.Append(Clause.ToString());
        sb.Append(',');
      }
      sb.Length--;
      sb.Append(") ");
      return sb.ToString();
    }

  }

}
+1

The type for IList must be known at compile time. Depending on what you want to do, you can display the list in IList or IEnumerable (without generics) and then iterate over the objects

0
source

Source: https://habr.com/ru/post/1710358/


All Articles