Click here to Skip to main content
15,880,854 members
Please Sign up or sign in to vote.
4.40/5 (5 votes)
See more:
We have typedef in C but what about c#
if I look at this example in C
C#
typedef struct record {
  int value;
} record;


I wrote this code
C#
public struct record
{
    public int value;
    public record(int v)
    {
        value = v;
    }
}


1- is it correct to represent the same thing by typedef in C code
2- is it the only way to transfer typedef in the c code to C#.if there is another way please tell me
thanks
Posted

There are two ways depending on the scope you need.

If you only need this within one .cs file then you can use the using directive to achieve this.
C#
using record = System.Int32;


If you need it across multiple files then a simple struct as a wrapper will do the job.
C#
/// <summary>
/// A wrapper around <see cref="System.Int32"/>.
/// </summary>
public struct Record
{
    // A struct's fields should not be exposed
    private int value;

    // As we are using implicit conversions we can keep the constructor private
    private Record(int value)
    {
        this.value = value;
    }

    /// <summary>
    /// Implicitly converts a <see cref="System.Int32"/> to a Record.
    /// </summary>
    /// <param name="value">The <see cref="System.Int32"/> to convert.</param>
    /// <returns>A new Record with the specified value.</returns>
    public static implicit operator Record(int value)
    {
        return new Record(value);
    }
    /// <summary>
    /// Implicitly converts a Record to a <see cref="System.Int32"/>.
    /// </summary>
    /// <param name="record">The Record to convert.</param>
    /// <returns>
    /// A <see cref="System.Int32"/> that is the specified Record's value.
    /// </returns>
    public static implicit operator int(Record record)
    {
        return record.value;
    }
}

As Record is implicitly converted to/from int, we get all the functionality of System.Int32 for free!
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 31-Dec-10 11:12am    
If should be noted, that your first line of code ("using record = ") introduces exact synonym of Int32 -- no conversion is performed, no difference in compiled code between if you use "record" or "System.Int32". The big problem is: there is no similar way to use it across files.
typedef class ...

C#
#region TypeDefine
    public class typedef
    {
        #region Variables
        protected T m_value;
        #endregion

        #region Constructor/Destructor
        public typedef()
        {
            this.m_value = default(T);
        }

        public typedef(T value)
        {
            this.m_value = value;
        }
        #endregion

        #region Override Methods
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return false;
            }
            if (!object.ReferenceEquals(this.m_value.GetType(), obj.GetType()))
            {
                return false;
            }
            return this.m_value.Equals(obj);
        }

        public override int GetHashCode()
        {
            return this.m_value.GetHashCode();
        }

        public override string ToString()
        {
            return this.m_value.ToString();
        }
        #endregion

        #region Static Methods

        private static bool IsNumeric(object value)
        {
            return ((value is sbyte) || (value is byte) || (value is short) || (value is ushort) || (value is int) || (value is uint) || (value is long) || (value is ulong) || (value is float) || (value is double) || (value is decimal));
        }

        private static bool IsInteger(object value)
        {
            return ((value is sbyte) || (value is byte) || (value is short) || (value is ushort) || (value is int) || (value is uint) || (value is long) || (value is ulong));
        }

        private static bool IsFloatingPoint(object value)
        {
            return ((value is float) || (value is double) || (value is decimal));
        }

        private static decimal GetNumeric(object value)
        {
            if (!IsNumeric(value))
            {
                throw new InvalidOperationException();
            }
            return (decimal)Convert.ChangeType((object)value, TypeCode.Decimal);
        }

        private static long GetInteger(object value)
        {
            if (!IsInteger(value))
            {
                throw new InvalidOperationException();
            }
            return (long)Convert.ChangeType((object)value, TypeCode.Int64);
        }

        private static decimal GetFloatingPoint(object value)
        {
            if (!IsFloatingPoint(value))
            {
                throw new InvalidOperationException();
            }
            return (decimal)Convert.ChangeType((object)value, TypeCode.Decimal);
        }

        #region Convertional operators
        public static implicit operator typedef(T value)
        {
            return new typedef(value);
        }

        public static explicit operator T(typedef value)
        {
            return value.Value;
        }
        #endregion

        #region Unary operators  { +, -, !, ~, ++, --, true, false }
        public static T operator +(typedef operand)
        {
            T temp = operand.m_value;
            if (IsInteger(temp))
            {
                return (T)(object)(+GetInteger(temp));
            }
            else if (IsFloatingPoint(temp))
            {
                return (T)(object)(+GetFloatingPoint(temp));
            }

            return temp;
        }

        public static T operator -(typedef operand)
        {
            T temp = operand.m_value;
            if (IsInteger(temp))
            {
                return (T)(object)(-GetInteger(temp));
            }
            else if (IsFloatingPoint(temp))
            {
                return (T)(object)(-GetFloatingPoint(temp));
            }

            return temp;
        }

        public static T operator !(typedef operand)
        {
            T temp = operand.m_value;
            if (temp is bool)
            {
                return (T)(object)(!((bool)Convert.ChangeType((object)temp, TypeCode.Boolean)));
            }
            else if (IsNumeric(temp))
            {
                decimal val = (decimal)Convert.ChangeType((object)temp, TypeCode.Decimal);
                return (T)(object)((val != 0) ? 0 : val);
            }
            else
            {
                try
                {
                    bool isNull = object.ReferenceEquals(((object)temp), null);
                    return ((isNull) ? ((T)(object)null) : temp);
                }
                catch (Exception)
                {
                    throw new InvalidOperationException();
                }
            }
        }

        public static T operator ~(typedef operand)
        {
            T temp = operand.m_value;
            if (IsInteger(temp))
            {
                return (T)(object)(~GetInteger(temp));
            }

            return temp;
        }

        public static bool operator true(typedef operand)
        {
            T temp = operand.m_value;

            if (temp is bool)
            {
                return (bool)Convert.ChangeType((object)temp, TypeCode.Boolean);
            }
            else if (temp is char)
            {
                return ((char)Convert.ChangeType((object)temp, TypeCode.Char) != '\0');
            }
            else if (temp is string)
            {
                return string.IsNullOrEmpty((string)(object)temp);
            }
            else if (IsInteger(temp))
            {
                return ((long)Convert.ChangeType((object)temp, TypeCode.Int64) > 0);
            }
            else if (IsFloatingPoint(temp))
            {
                return ((decimal)Convert.ChangeType((object)temp, TypeCode.Decimal) > 0);
            }
            else
            {
                try
                {
                    return !object.ReferenceEquals(((object)temp), null);
                }
                catch (Exception)
                {
                    throw new InvalidOperationException();
                }
            }
        }

        public static bool operator false(typedef operand)
        {
            if (operand)
            {
                return false;
            }
            return true;
        }
        #endregion

        #region Binary operators { +, -, *, /, %, &, |, ^, <<, >> }
        public static T operator +(typedef left, typedef right)
        {
            T tempLeft = left.m_value;
            T tempRight = right.m_value;

            if ((tempLeft is string) && (tempRight is string))
            {
                return (T)(object)(((string)(object)tempLeft) + ((string)(object)tempRight));
            }
            else if (IsNumeric(tempLeft) && IsNumeric(tempRight))
            {
                return (T)(object)(GetNumeric((object)tempLeft) + GetNumeric((object)tempRight));
            }

            return tempLeft;
        }

        public static T operator -(typedef left, typedef right)
        {
            T tempLeft = left.m_value;
            T tempRight = right.m_value;

            if (IsNumeric(tempLeft) && IsNumeric(tempRight))
            {
                return (T)(object)(GetNumeric((object)tempLeft) - GetNumeric((object)tempRight));
            }

            return tempLeft;
        }

        public static T operator *(typedef left, typedef right)
        {
            T tempLeft = left.m_value;
            T tempRight = right.m_value;

            if (IsNumeric(tempLeft) && IsNumeric(tempRight))
            {
                return (T)(object)(GetNumeric((object)tempLeft) * GetNumeric((object)tempRight));
            }

            return tempLeft;
        }

        public static T operator /(typedef left, typedef right)
        {
            T tempLeft = left.m_value;
            T tempRight = right.m_value;

            if (IsNumeric(tempLeft) && IsNumeric(tempRight))
            {
                return (T)(object)(GetNumeric((object)tempLeft) / GetNumeric((object)tempRight));
            }

            return tempLeft;
        }

        public static T operator %(typedef left, typedef right)
        {
            T tempLeft = left.m_value;
            T tempRight = right.m_value;

            if (IsNumeric(tempLeft) && IsNumeric(tempRight))
            {
                return (T)(object)(GetNumeric((object)tempLeft) % GetNumeric((object)tempRight));
            }

            return tempLeft;
        }

        public static T operator &(typedef left, typedef right)
        {
            T tempLeft = left.m_value;
            T tempRight = right.m_value;

            if (IsInteger(tempLeft) && IsInteger(tempRight))
            {
                return (T)(object)(GetInteger((object)tempLeft) & GetInteger((object)tempRight));
            }

            return tempLeft;
        }

        public static T operator |(typedef left, typedef right)
        {
            T tempLeft = left.m_value;
            T tempRight = right.m_value;

            if (IsInteger(tempLeft) && IsInteger(tempRight))
            {
                return (T)(object)(GetInteger((object)tempLeft) | GetInteger((object)tempRight));
            }

            return tempLeft;
        }

        public static T operator ^(typedef left, typedef right)
        {
            T tempLeft = left.m_value;
            T tempRight = right.m_value;

            if (IsInteger(tempLeft) && IsInteger(tempRight))
            {
                return (T)(object)(GetInteger((object)tempLeft) ^ GetInteger((object)tempRight));
            }

            return tempLeft;
        }

        public static T operator <<(typedef left, int right)
        {
            T tempLeft = left.m_value;

            if (IsInteger(tempLeft))
            {
                return (T)(object)(GetInteger((object)tempLeft) << right);
            }

            return tempLeft;
        }

        public static T operator >>(typedef left, int right)
        {
            T tempLeft = left.m_value;

            if (IsInteger(tempLeft))
            {
                return (T)(object)(GetInteger((object)tempLeft) >> right);
            }

            return tempLeft;
        }
        #endregion

        #region Comparison operators { ==, !=, <, >, <=, >= }
        public static bool operator ==(typedef left, typedef right)
        {
            //return value1.Value == value2.Value;
            return left.Equals(right);
        }

        public static bool operator !=(typedef left, typedef right)
        {
            //return left.Value != value2.Value;
            return !(left.Equals(right));
        }

        public static bool operator <(typedef left, typedef right)
        {
            T tempLeft = left.m_value;
            T tempRight = right.m_value;

            if (IsNumeric(tempLeft) && IsNumeric(tempRight))
            {
                return (GetNumeric((object)tempLeft) < GetNumeric((object)tempRight));
            }

            return false;
        }

        public static bool operator >(typedef left, typedef right)
        {
            T tempLeft = left.m_value;
            T tempRight = right.m_value;

            if (IsNumeric(tempLeft) && IsNumeric(tempRight))
            {
                return (GetNumeric((object)tempLeft) > GetNumeric((object)tempRight));
            }

            return false;
        }

        public static bool operator <=(typedef left, typedef right)
        {
            T tempLeft = left.m_value;
            T tempRight = right.m_value;

            if (IsNumeric(tempLeft) && IsNumeric(tempRight))
            {
                return (GetNumeric((object)tempLeft) <= GetNumeric((object)tempRight));
            }

            return false;
        }

        public static bool operator >=(typedef left, typedef right)
        {
            T tempLeft = left.m_value;
            T tempRight = right.m_value;

            if (IsNumeric(tempLeft) && IsNumeric(tempRight))
            {
                return (GetNumeric((object)tempLeft) >= GetNumeric((object)tempRight));
            }

            return false;
        }
        #endregion

        #endregion

        #region Properties
        public virtual T Value
        {
            get { return this.m_value; }
            set { this.m_value = value; }
        }
        #endregion
    }
    #endregion


and usage ...

C#
//typedef unsigned char       VTBYTE;
    public class VTBYTE : typedef<byte>
    {
        #region Constructor
        public VTBYTE()
            : base()
        { }

        public VTBYTE(byte value)
            : base(value)
        { }
        #endregion
    }
 
Share this answer
 
v2
Comments
Member 12234919 8-Jan-17 13:30pm    
Sorry for the silly question, but what is the reference for the 'T'-s?
c# doesn't support typedef.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 1-Mar-11 3:55am    
Of course not, my 5.
--SA
1) Even with C++, you do need keyword "typedef" to declare structure or class. I think this is C anachronism.
2) C# structure is semantically the closest to C++; with classes, for example, there are much more differences. C# structure carry value semantic, but C# classes -- reference semantics and a lot more differences.

Consider alternative: using C++/CLI, not C#
 
Share this answer
 
Comments
Espen Harlinn 28-Feb-11 15:40pm    
It's sorely missed sometimes, a 5
Sergey Alexandrovich Kryukov 1-Mar-11 3:55am    
Thank you.
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900