Solved

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

Posted on 2016-09-09
5
181 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
5 Comments
 
LVL 75

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 100 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 34

Accepted Solution

by:
it_saige earned 400 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

Creating Instructional Tutorials  

For Any Use & On Any Platform

Contextual Guidance at the moment of need helps your employees/users adopt software o& achieve even the most complex tasks instantly. Boost knowledge retention, software adoption & employee engagement with easy solution.

Question has a verified solution.

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

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…

617 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