Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

C# cannot access non-static property in static context from base class

Posted on 2016-09-09
5
Medium Priority
?
319 Views
Last Modified: 2016-09-12
I do not understand what I am doing wrong:

Base Class:
using System;

namespace Common
{
    public class CommonBase
    {
        public DateTime DateTimeNullValue { get; set; }
        public Guid GuidNullValue { get; set; }
        public int IntNullValue { get; set; }
        public float FloatNullValue { get; set; }
        public decimal DecimalNullValue { get; set; }
        public string StringNullValue { get; set; }
    }
}

Open in new window


Derived class:
namespace Common
{
    public abstract class DtoBase : CommonBase
    {
        public bool IsNew { get; set; }
    }
}

Open in new window


Abstract class:
using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;

namespace DAL
{
    public abstract class DalBase
    {
        // CreateParameter - uniqueidentifier
        protected static SqlParameter CreateParameter(string name, Guid value)
        {
            if (value.Equals(Common.DtoBase.GuidNullValue)) // Error at GuidNullValue
            {
                // If value is null then create a null parameter
                return CreateNullParameter(name, SqlDbType.UniqueIdentifier);
            }
            else
            {
                var parameter = new SqlParameter
                {
                    SqlDbType = SqlDbType.UniqueIdentifier,
                    ParameterName = name,
                    Value = value,
                    Direction = ParameterDirection.Input
                };
                return parameter;
            }
        }
    }
}

Open in new window


Get error trying to use GuidNullValue in the method.  Why can I not call it through the derived class?
0
Comment
Question by:Tim Word
  • 2
  • 2
5 Comments
 
LVL 75

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 400 total points
ID: 41791342
This syntax:

Common.DtoBase.GuidNullValue

...doesn't make sense. Your classes are not static. They have to be instantiated. You can only refer to your properties by way of an instance. Either that, or you need to change your properties to be static, which wouldn't make sense to me..at least from what I see above.
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 41791343
Also, what is the goal here?
0
 

Author Comment

by:Tim Word
ID: 41791419
protected static SqlParameter CreateParameter is static.  CommonBase and DtoBase is creating a null for each type to be used in DAL, BAL, GUI, etc. So, the DalBase (Data Access Layer Base) class is using the null reference of the type GUID to test if the passed GUID value is null return Null Parameter else create a returned parameter.

        // CreateNullParameter
        protected static SqlParameter CreateNullParameter(string name, SqlDbType paramType)
        {
            SqlParameter parameter = new SqlParameter
            {
                SqlDbType = paramType,
                ParameterName = name,
                Direction = ParameterDirection.Input
            };
            return parameter;
        }

        // CreateNullParameter - with size for nvarchars
        protected static SqlParameter CreateNullParameter(string name, SqlDbType paramType, int size)
        {
            SqlParameter parameter = new SqlParameter
            {
                SqlDbType = paramType,
                ParameterName = name,
                Size = size,
                Value = null,
                Direction = ParameterDirection.Input
            };
            return parameter;
        }

Open in new window

0
 
LVL 35

Accepted Solution

by:
it_saige earned 1600 total points
ID: 41791631
What Kaufmed is saying is that the classes you have presented (Base, Derived and Abstract) are not static, therefore in order to use their non-static members you have to instantiate the class; e.g. -
namespace Common
{
	public class CommonBase
	{
		public DateTime DateTimeNullValue { get; set; }
		public Guid GuidNullValue { get; set; }
		public int IntNullValue { get; set; }
		public float FloatNullValue { get; set; }
		public decimal DecimalNullValue { get; set; }
		public string StringNullValue { get; set; }
	}

	public class DtoBase : CommonBase
	{
		public bool IsNew { get; set; }
	}
}

namespace DAL
{
	public abstract class DalBase
	{
		// CreateParameter - uniqueidentifier
		protected static SqlParameter CreateParameter(string name, Guid value)
		{
			if (value.Equals(new Common.DtoBase().GuidNullValue)) // Error at GuidNullValue
			{
				// If value is null then create a null parameter
				return CreateNullParameter(name, SqlDbType.UniqueIdentifier);
			}
			else
			{
				var parameter = new SqlParameter
				{
					SqlDbType = SqlDbType.UniqueIdentifier,
					ParameterName = name,
					Value = value,
					Direction = ParameterDirection.Input
				};
				return parameter;
			}
		}
	}
}

Open in new window

Get's rid of your error.

I believe that I understand what you want to accomplish, this (unfortunately) will not give you the results that you want.

Why?

Well because you state (in your code) that these will be null values and the only one that is actually nullable (by default) and therefore can contain a null value is *string*.

Proof?

Consider the following:
using System;
using System.Reflection;

namespace EE_Q28968768
{
	class Program
	{
		static void Main(string[] args)
		{
			var defaults = new Defaults();
			defaults.PrintPropertyInformation();
			Console.ReadLine();
		}
	}

	class Defaults
	{
		public DateTime DateTime { get; set; }
		public Guid Guid { get; set; }
		public short Short { get; set; }
		public ushort UShort { get; set; }
		public int Integer { get; set; }
		public uint UInteger { get; set; }
		public long Long { get; set; }
		public ulong ULong { get; set; }
		public double Double { get; set; }
		public float Float { get; set; }
		public decimal Decimal { get; set; }
		public char Character { get; set; }
		public string String { get; set; }
		public IntPtr IntPtr { get; set; }
	}

	static class Extensions
	{
		public static bool IsNullOrDefault<T>(this T source)
		{
			if (source == null) return true;
			if (object.Equals(source, default(T))) return true;
			Type methodType = typeof(T);
			if (Nullable.GetUnderlyingType(methodType) != null) return false;
			Type argumentType = source.GetType();
			if (argumentType.IsValueType && argumentType != methodType)
			{
				object o = Activator.CreateInstance(source.GetType());
				return o.Equals(source);
			}
			return false;
		}

		public static bool IsNullable(this object source)
		{
			if (source == null) return true; // No need to go any further, since the source equals null we know it supports null.
			Type type = source.GetType();
			if (!type.IsValueType) return true; // Reference types are nullable by default.  Value types are not.
			if (Nullable.GetUnderlyingType(type) != null) return true; // Nullable<T> or ? has been declared for this type implementation.
			return false; // Standard value type, not made nullable.
		}

		public static void PrintPropertyInformation<T>(this T source)
		{
			if (source != null)
			{
				Console.WriteLine("Displaying properties for {0}", typeof(T).Name);
				foreach (PropertyInfo property in typeof(T).GetProperties())
				{
					var value = property.GetValue(source, null);
					Console.WriteLine("Name: {0}; Value: {1}; IsNullOrDefault: {2}; IsNull: {3}; IsNullable: {4}", property.Name, value, value.IsNullOrDefault(), (value == null), value.IsNullable());
				}
			}
		}
	}
}

Open in new window

Which produces the following output -Capture.JPGIn order to change this behaviour so that you can support your nullable values, you must either use 'Nullable<T>' or the nullable operator, '?'; e.g. -
class Defaults
{
	public Nullable<DateTime> DateTime { get; set; }
	public Nullable<Guid> Guid { get; set; }
	public Nullable<short> Short { get; set; }
	public Nullable<ushort> UShort { get; set; }
	public Nullable<int> Integer { get; set; }
	public Nullable<uint> UInteger { get; set; }
	public Nullable<long> Long { get; set; }
	public Nullable<ulong> ULong { get; set; }
	public Nullable<double> Double { get; set; }
	public Nullable<float> Float { get; set; }
	public Nullable<decimal> Decimal { get; set; }
	public Nullable<char> Character { get; set; }
	public string String { get; set; }
	public Nullable<IntPtr> IntPtr { get; set; }
}

Open in new window

-Or-
class Defaults
{
	public DateTime? DateTime { get; set; }
	public Guid? Guid { get; set; }
	public short? Short { get; set; }
	public ushort? UShort { get; set; }
	public int? Integer { get; set; }
	public uint? UInteger { get; set; }
	public long? Long { get; set; }
	public ulong? ULong { get; set; }
	public double? Double { get; set; }
	public float? Float { get; set; }
	public decimal? Decimal { get; set; }
	public char? Character { get; set; }
	public string String { get; set; }
	public IntPtr? IntPtr { get; set; }
}

Open in new window

Each of which change the output accordingly -Capture.JPG
But why try to reinvent the wheel.  .NET already has methods with which to determine the if the type supports null-ability and retrieving the underlying value type.  In reality, I believe you are probably trying to do something like:
static class Extensions
{
	public static bool IsNullOrDefault<T>(this T source)
	{
		if (source == null) return true;
		if (object.Equals(source, default(T))) return true;
		Type methodType = typeof(T);
		if (Nullable.GetUnderlyingType(methodType) != null) return false;
		Type argumentType = source.GetType();
		if (argumentType.IsValueType && argumentType != methodType)
		{
			object o = Activator.CreateInstance(source.GetType());
			return o.Equals(source);
		}
		return false;
	}

	public static bool IsNullable(this object source)
	{
		if (source == null) return true; // No need to go any further, since the source equals null we know it supports null.
		Type type = source.GetType();
		if (!type.IsValueType) return true; // Reference types are nullable by default.  Value types are not.
		if (Nullable.GetUnderlyingType(type) != null) return true; // Nullable<T> or ? has been declared for this type implementation.
		return false; // Standard value type, not made nullable.
	}

	public static SqlParameter CreateParameter<T>(this T value, string name, int size = -1)
	{
		SqlParameter result = default(SqlParameter);
		try
		{
			result.Direction = ParameterDirection.Input;
			result.ParameterName = name;
			if (size > -1)
				result.Size = size;
			if (!value.IsNullable())
			{
				result.SqlDbType = DbTypeMapper.ToSqlDbType(typeof(T));
				result.Value = value;
			}
			else
			{
				result.SqlDbType = DbTypeMapper.ToSqlDbType(value.GetType());
				result.Value = null;
			}
		}
		catch (Exception)
		{
			// Exception thrown.  Log it?
			result = default(SqlParameter);
		}
		return result;
	}
}

public sealed class DbTypeMapper
{
	/// <summary>Struct DbTypeMapEntry</summary>
	private struct DbTypeMapEntry
	{
		/// <summary>Gets the Type.</summary>
		/// <value>The Type.</value>
		public Type Type { get; private set; }

		/// <summary>Gets the DbType.</summary>
		/// <value>The DbType.</value>
		public DbType DbType { get; private set; }

		/// <summary>Gets the SqlDbType.</summary>
		/// <value>The SqlDbType.</value>
		public SqlDbType SqlDbType { get; private set; }

		/// <summary>Initializes a new instance of the <see cref="DbTypeMapEntry"/> struct.</summary>
		/// <param name="type">The Type.</param>
		/// <param name="dbType">The DbType.</param>
		/// <param name="sqlDbType">The SqlDbType.</param>
		public DbTypeMapEntry(Type type, DbType dbType, SqlDbType sqlDbType) : this()
		{
			Type = type;
			DbType = dbType;
			SqlDbType = sqlDbType;
		}

		/// <summary>Returns a <see cref="System.String" /> that represents this instance.</summary>
		/// <returns>A <see cref="System.String" /> that represents this instance.</returns>
		public override string ToString()
		{
			return string.Format("Type: {0}; DBType: {1}; SqlDbType: {2}", Type.FullName, DbType, SqlDbType);
		}
	}

	private static readonly List<Nullable<DbTypeMapEntry>> TypeMapEntries;
	public static void PrintEntries()
	{
		foreach (var entry in TypeMapEntries)
			Console.WriteLine(entry);
	}

	#region "Constructors"
	/// <summary>Initializes static members of the <see cref="DbTypeMapper" /> class.</summary>
	static DbTypeMapper()
	{
		if (TypeMapEntries == null)
		{
			TypeMapEntries = new List<Nullable<DbTypeMapEntry>> 
			{
				new DbTypeMapEntry(typeof(bool), DbType.Boolean, SqlDbType.Bit),
				new DbTypeMapEntry(typeof(byte), DbType.Double, SqlDbType.TinyInt),
				new DbTypeMapEntry(typeof(byte[]), DbType.Binary, SqlDbType.Image),
				new DbTypeMapEntry(typeof(DateTime), DbType.DateTime, SqlDbType.DateTime),
				new DbTypeMapEntry(typeof(Decimal), DbType.Decimal, SqlDbType.Decimal),
				new DbTypeMapEntry(typeof(double), DbType.Double, SqlDbType.Float),
				new DbTypeMapEntry(typeof(Guid), DbType.Guid, SqlDbType.UniqueIdentifier),
				new DbTypeMapEntry(typeof(Int16), DbType.Int16, SqlDbType.SmallInt),
				new DbTypeMapEntry(typeof(Int32), DbType.Int32, SqlDbType.Int),
				new DbTypeMapEntry(typeof(Int64), DbType.Int64, SqlDbType.BigInt),
				new DbTypeMapEntry(typeof(object), DbType.Object, SqlDbType.Variant),
				new DbTypeMapEntry(typeof(string), DbType.String, SqlDbType.VarChar),
				new DbTypeMapEntry(typeof(string), DbType.String, SqlDbType.NVarChar)
			};
		}
	}

	/// <summary>Prevents a default instance of the <see cref="DbTypeMapper"/> class from being created.</summary>
	private DbTypeMapper() { ;}
	#endregion

	#region "Methods"
	/// <summary>Convert db type to .Net data type</summary>
	/// <param name="dbType">The DbType to find.</param>
	/// <returns>Type.</returns>
	public static Type ToNetType(DbType dbType)
	{
		return Find(dbType).Type;
	}

	/// <summary>Convert TSQL type to .Net data type</summary>
	/// <param name="sqlDbType">The SqlDbType to find.</param>
	/// <returns>Type.</returns>
	public static Type ToNetType(SqlDbType sqlDbType)
	{
		return Find(sqlDbType).Type;
	}

	/// <summary>Convert TSQL type to .Net data type</summary>
	/// <param name="name">The name of the SqlDbType to find.</param>
	/// <returns>Type.</returns>
	public static Type ToNetType(string name)
	{
		return Find(name).Type;
	}

	/// <summary>Convert .Net type to Db type</summary>
	/// <param name="type">The type to find.</param>
	/// <returns>DbType.</returns>
	public static DbType ToDbType(Type type)
	{
		return Find(type).DbType;
	}

	/// <summary>Convert TSQL data type to DbType</summary>
	/// <param name="sqlDbType">The SqlDbType to find.</param>
	/// <returns>DbType.</returns>
	public static DbType ToDbType(SqlDbType sqlDbType)
	{
		return Find(sqlDbType).DbType;
	}

	/// <summary>Convert TSQL data type to DbType</summary>
	/// <param name="name">The name of the SqlDbType to find.</param>
	/// <returns>DbType.</returns>
	public static DbType ToDbType(string name)
	{
		return Find(name).DbType;
	}

	/// <summary>Convert .Net type to TSQL data type</summary>
	/// <param name="type">The type to find.</param>
	/// <returns>SqlDbType.</returns>
	public static SqlDbType ToSqlDbType(Type type)
	{
		return Find(type).SqlDbType;
	}

	/// <summary>Convert DbType type to TSQL data type</summary>
	/// <param name="dbType">The DbType to find.</param>
	/// <returns>SqlDbType.</returns>
	public static SqlDbType ToSqlDbType(DbType dbType)
	{
		return Find(dbType).SqlDbType;
	}

	/// <summary>Convert DbType type to TSQL data type</summary>
	/// <param name="name">The name of the DbType to find.</param>
	/// <returns>SqlDbType.</returns>
	public static SqlDbType ToSqlDbType(string name)
	{
		return Find(name).SqlDbType;
	}

	private static DbTypeMapEntry Find(Type type)
	{
		var result = TypeMapEntries.FirstOrDefault(x => x.HasValue && (x.Value.Type == (Nullable.GetUnderlyingType(type) ?? type)));
		if (result == null)
			throw new ApplicationException("Referenced an unsupported Type");
		return result.Value;
	}

	private static DbTypeMapEntry Find(DbType dbType)
	{
		var result = TypeMapEntries.FirstOrDefault(x => x.HasValue && (x.Value.DbType == dbType));
		if (result == null)
			throw new ApplicationException("Referenced an unsupported Type");
		return result.Value;
	}

	private static DbTypeMapEntry Find(SqlDbType sqlDbType)
	{
		var result = TypeMapEntries.FirstOrDefault(x => x.HasValue && (x.Value.SqlDbType == sqlDbType));
		if (result == null)
			throw new ApplicationException("Referenced an unsupported Type");
		return result.Value;
	}

	private static DbTypeMapEntry Find(string name)
	{
		var result = TypeMapEntries.FirstOrDefault(x => x.HasValue && x.ToString().IndexOf(name, StringComparison.OrdinalIgnoreCase) > -1);
		if (result == null)
			throw new ApplicationException("Referenced an unsupported Type");
		return result.Value;
	}
	#endregion
}

Open in new window


-saige-
1
 

Author Closing Comment

by:Tim Word
ID: 41794317
Thanks to you both.  I will rework the code. Trying to do EF without using EF.
0

Featured Post

NEW Veeam Backup for Microsoft Office 365 1.5

With Office 365, it’s your data and your responsibility to protect it. NEW Veeam Backup for Microsoft Office 365 eliminates the risk of losing access to your Office 365 data.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
This video shows how to quickly and easily deploy an email signature for all users in Office 365 and prevent it from being added to replies and forwards. (the resulting signature is applied on the server level in Exchange Online) The email signat…
Whether it be Exchange Server Crash Issues, Dirty Shutdown Errors or Failed to mount error, Stellar Phoenix Mailbox Exchange Recovery has always got your back. With the help of its easy to understand user interface and 3 simple steps recovery proced…
Suggested Courses

877 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question