1

I have an external library I am using, namely Aspose.Email.dll (available on NuGet). It has a PageInfo class. Go To Definition shows the following for it in Visual Studio:

using System;

namespace Aspose.Email
{
    public class PageInfo
    {
        protected PageInfo next;

        public int AbsoluteOffset { get; }
        public int ItemsPerPage { get; }
        public bool LastPage { get; }
        public virtual PageInfo NextPage { get; }
        public int PageOffset { get; }
        public int TotalCount { get; }
    }
}

Long story short, I need to create a PageInfo object. How can I create one using Reflection and also set its ItemsPerPage property?

I have tried this:

var result = (PageInfo)FormatterServices.GetUninitializedObject(typeof(PageInfo));
typeof(PageInfo).GetProperty("ItemsPerPage", BindingFlags.Instance | BindingFlags.Public).SetValue(result, 1);

The problem is that SetValue errors out with Property set method not found.

2
  • What are you doing that you need to create a PageInfo? Perhaps if you ask a new question about "How can I do X without crateing my own PageInfo?" you may have a solution better than using reflection. Commented Jul 14, 2016 at 18:22
  • I was afraid someone might ask. I am programming an abstract interface library to consolidate two different mail libraries I am using together (this and the Exchange library) I am trying to consolidate a way of paging data between the two. Unfortunately a big caveat with this IMAP library is that you can't really build an arbitrary paging query, but must always use a linked paging object after you first make a call to get paged data. Its because of the nature of the library and how its API was implemented that it becomes a bit of a pain. Commented Jul 14, 2016 at 19:06

1 Answer 1

2

Getter-only properties do not have setters. They use a readonly backing field that can only be set in the constructor.

You can change the properties to have private setter, e.g.

public int ItemsPerPage { get; private set; }

If you do not have access to the code, you can find the matching field using GetField and set its value.

typeof(PageInfo).GetTypeInfo().DeclaredFields
    .First(f => f.Name.Contains("ItemsPerPage")).SetValue(result, 1);
Sign up to request clarification or add additional context in comments.

6 Comments

Can't change the library as I don't have the source, so I can't edit the ItemsPerPage property.
Checking the library using dotPeek, and also enumerating through the DeclaredFields...I am at a bit of an impass, because...their named fields contain names such as #=qOeu6uj6DPtGwJ1qAj8pvJQ== and #=qQACP_gKR9skNS8JCd3aPRw==, leading me to believe they are hashing them or something for each version of the library, which sucks because upgrade-ability goes out the window...
What do you mean when you say to grab the field name from the getter and use it? Oh, you mean just use the named fields like #=qOeu6uj6DPtGwJ1qAj8pvJQ==?
I was hoping to avoid that. I guess there's no other way huh? I will park the issue for now then...
It's not a sealed class, so can you create your subclass of PageInfo, and override that ItemsPerPage property using the 'new' keyword? public new int ItemsPerPage { get; set; } ??
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.