Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / New Users / August 2004

Tip: Looking for answers? Try searching our database.

Derived method GetObjectData  .... can not reduce access.  (runtime error)

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Steven Ireland - 28 Aug 2004 10:44 GMT
I'm getting the follow message when I try to call a routine which creates an
instance of my class TG.ADO.DataConnector.ADOConnectorColumn.

The calling code is

                //
                try {Inquire();}
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.Message);
                }
                catch {}

The runtime error is

Derived method GetObjectData in type TG.ADO.DataConnector.ADOConnectorColumn
from assembly TG.ADO, Version=4.3.13.1, Culture=neutral,
PublicKeyToken=d6af0e7fcb70d177 can not reduce access.

The Inquire() method is

        public override bool Inquire()
        {
                bool bNeedToOpen = (_adoConn == null);

                ADODB.Recordset rs = null;
                try
                {
                    // OleDbConnection
                    if (bNeedToOpen)
                    {
                        //                    // Skip if couldn't open the file.
                        _adoConn = ADOHelper.OpenConnection(ConnectionString,
ADODB.ConnectOptionEnum.adConnectUnspecified);
                        if (_adoConn == null)
                            return false;
                    }

                    // Get a recordset from the table
                    Object RecordsAffected = null;
                    string cmdStr = String.Format(@"select * from {0}", _Name);
                    rs = _adoConn.Execute(cmdStr, out RecordsAffected, (int)
ADODB.CommandTypeEnum.adCmdText);

                    // Clear the schema information
                    Schema.Clear();

                    // Loop over the fields and update the summary information.
                    StringCollection fields = new StringCollection();
                    foreach (ADODB.Field field in rs.Fields)
                    {
                        fields.Add(field.Name);

                        // Add the field to the schema
                        TG.Data.DataColumn dc = new ADOConnectorColumn(field);
                       
                        Schema.Columns.Add(dc);
                    }
                   
                    _SummaryInfo["Columns"] = fields;
                }
                catch {}
                finally
                {
                    if (rs != null)
                        rs.Close();

                    // Close if needed
                    if (bNeedToOpen)
                    {
                        _adoConn.Close();
                        _adoConn = null;
                    }
                }

            return true;
  }

but the first line of the method isn't being reached (i.e. the runtime is
throwing the exception before invoking the method).

The ADOConnectorColumn class is a C# class defined as

using System;
using System.Collections;
using System.ComponentModel;
using System.Runtime.Serialization;

using TG.Core;
using TG.Data;

namespace TG.ADO.DataConnector
{
    /// <summary>
    /// Summary description for ADOConnectorColumn.
    /// </summary>
    [Serializable]
    public class ADOConnectorColumn : TG.Data.DataColumn, ISerializable
    {
        protected ADOConnectorColumn() : this(string.Empty) {}

        public ADOConnectorColumn(string fieldname) : base(fieldname)
        {
        }
           
        public ADOConnectorColumn(ADODB.Field field) : this(field.Name)
        {
        }

        // -----------------------------------------
        #region // ISerializable
        protected ADOConnectorColumn(SerializationInfo info, StreamingContext
context) {}
        protected override void GetObjectData(SerializationInfo info,
StreamingContext context) {}
        #endregion

    }
}

TG.Data.DataColumn is a C++ managed abstract class. A derived class in the same
assembly as TG.Data.DataColumn works fine.

All the references are correct as far as I can see, and the entire project
builds with 0 errors and only 1 warning in the c++ class (LINK : warning
LNK4243: DLL containing objects compiled with /clr is not linked with /NOENTRY;
image may not run correctly). VS.net 2003/DX9 summer 2004 release/XPSP2.

Googling was no help.

Any suggestions?

TIA
Steve.
Steven Ireland - 28 Aug 2004 11:11 GMT
And as usually happens when I post a question to a newsgroup, I find a
workaround almost straight away :)

By changing the definition of

    protected override void GetObjectData(SerializationInfo info, StreamingContext
context) {}

to
    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext
context) {}

the code now works.

I'd tried various combinations of the ISerializable interface and the
[Serializable] attribute without success.

Does anybody know what the "can not reduce access" error means?

Steve.

>I'm getting the follow message when I try to call a routine which creates an
>instance of my class TG.ADO.DataConnector.ADOConnectorColumn.
[quoted text clipped - 130 lines]
>TIA
>Steve.
Steven Ireland - 29 Aug 2004 06:23 GMT
FYI, I believe the problem was the base class definition in the c++ project

        // --------------------------------------------------
        // ISerializable
    protected:
        MyDataColumn(SerializationInfo* info, StreamingContext context);
        virtual void GetObjectData(SerializationInfo* info, StreamingContext context);

This made GetObjectData protected. Derived classes in the same assembly worked fine.

However from another assembly, it looks like reflection is used to find a public GetObjectData
method in a derived class. As a public member couldn't be found, the runtime was unable to call
any method which declared an instance of the derived class.

By adding a public: access specifier, the problem went away ie

        // --------------------------------------------------
        // ISerializable
    protected:
        MyDataColumn(SerializationInfo* info, StreamingContext context);
 public:
        virtual void GetObjectData(SerializationInfo* info, StreamingContext context);

which is the correct ISerializable member definition.

I hope that helps someone else.

Steve.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.