본문 바로가기
PC&웹/VS프로그래밍

C#, Object 값 형식을 보관하는 일반화된 클래스

by Simulz 2022. 11. 8.
반응형

DevExpress의 컨트롤을 사용하면 값을 읽고 쓸 수 있는 EditValue 항목이 있다.

그런데 Object 형식이다 보니, 다른 곳에 값을 전달할 때 형변환을 해야하는 귀차니즘이 있다.
DataRow Column 값도 마찬가지.

그래서 자동으로 형변환을 해주는 클래스를 만들었다. 처음에는 변수 선언을 해야 하니 반자동...
(개인용이므로 참고만 할 것)

 

코드

/*
 * Update: 2022-11-08
 * Simulz
 */

/// <summary>
/// 레코드의 데이터와 컬럼 정보를 포함합니다.
/// </summary>
/// <typeparam name="T">데이터 형식</typeparam>
public record OleColumn<T> : object, IComparable<OleColumn<T>>
{
    public OleColumn()
    {
    }
    /// <summary>
    /// 컬럼명
    /// </summary>
    public string Name { get; set; }
    /// <summary>
    /// 데이터 값
    /// </summary>
    protected T fEditValue;
    /// <summary>
    /// 객체 형식의 값을 저장하거나 가져옵니다.
    /// </summary>
    public virtual object EditValue
    {
        get => fEditValue;
        set
        {
            if (value == DBNull.Value)
            {
                fEditValue = default;
            }
            else if (value == null) //! Nullable 확인할 것
            {
                fEditValue = default;
            }
            else
            {
                if (CSType == typeof(decimal))
                {
                    fEditValue = (T)Convert.ChangeType(Convert.ToDecimal(value), typeof(T));
                }
                else
                {
                    fEditValue = (T)value;
                }
            }

            if (!AllowDBNull && fEditValue == null)
            {
                if (CSType == typeof(string))
                    fEditValue = (T)(object)string.Empty;
                else if (CSType == typeof(Struct))
                    throw new NoNullAllowedException("Null 값을 허용하지 않습니다.");
            }
        }
    }
    /// <summary>
    /// 형식화된 값을 저장하거나 가져옵니다.
    /// </summary>
    public virtual T TypedValue { get => fEditValue; set => fEditValue = value; }
    /// <summary>
    /// DB 형식의 값을 가져옵니다.
    /// </summary>
    public object DbValue { get => (object)fEditValue ?? DBNull.Value; }
    /// <summary>
    /// C# 데이터 형식을 가져옵니다.
    /// </summary>
    public Type CSType { get => typeof(T); }
    /// <summary>
    /// DB 데이터 형식을 저장하거나 가져옵니다.
    /// </summary>
    public OleDbType OleDbType { get; set; }
    /// <summary>
    /// Null 값 허용 여부
    /// </summary>
    public bool AllowDBNull { get; set; }
    /// <summary>
    /// 데이터 길이
    /// </summary>
    public int Size { get; set; }

    int IComparable<OleColumn<T>>.CompareTo(OleColumn<T> other)
    {
        if (other == null) throw new NullReferenceException();

        if (CSType == other.CSType)
        {
            if (EqualityComparer<T>.Default.Equals(fEditValue, other.fEditValue))
            {
                return 0;
            }
            else
            {
                return -1;
            }
        }
        else
        {
            return -1;
        }
    }
}

잡다한게 많은 이유는 DataTable, Database에 사용해야 해서...

 

사용

클래스 내에서 선언
public OleColumn<decimal> DEC { get; set; }

메소드 내에서 정의
DEC = new() { Name = "가격", OleDbType = OleDbType.Decimal, EditValue = value };


사용
값을 연산할 때
editDEC.EditValue = Math.Abs(DEC.TypedValue);

DataRow에서 인덱싱할 때
editDEC.EditValue = dataRow[DEC.Name];

개체.TypedValue를 사용하면 형변환된 값을 가져올 수 있다. 위의 예에서는 Math.Abs(decimal 값)이 된다.

DataRow에서 컬럼 인덱싱할 때, 문자열은 리팩토리가 안 되고 인텔리센스가 안 되니 오류 위험이 많은데, 위처럼 개체.Name을 사용하면 알아서 문자열 값을 적용한다.

반응형

태그

댓글0