Can't Access Property of Public Interface - c#

I've defined a simple interface:
public interface Categorizable {
string Category { get; set; }
}
Elsewhere, I try to use it in a function:
public void Add(Categorizable item)
{
string cat = item.Category;
}
However, Visual Studio tells me "Categorizable does not contain a definition for Category".
How do I fix this so that Category can be used as an accessible property?

Interfaces should really have an I in front of them i. ICategorizable, its very common and a standard for C#.
Check you haven't declared a class with the same name.
Check you haven't declared your interface somewhere else.
If this is coming from a class library, check you are actually using the correct version, and its builds with your project.
Other than this, there isn't much else that can go wrong. This is how interfaces work (without deviation).

Related

Use reflection/generics to generate wrapper class

I'd like to create a wrapper class dynamically, such that for every desired class (probably underneath a certain namespace like DBO) I'll get an appropriate class like this:
public class [ClassName]Wrapper{
public [ClassName] [ClassName] { get; set; }
}
Second, I need to if based on wrapper vs original type. I'm assuming I can just do something like:
(classBob as Type).ToString().EndsWith("Wrapper")
If I require anything more, please help me out :).
I'm fairly new to reflection and I've never built a class at runtime. Code to do this would be great, but even pointing out excellent resources to study up on the tools used to do this would be a great move forward for me.
Thanks!
Wouldn't using generics solve your problem?
public class Wrapper<T>
where T : class
{
public Wrapper(T wrappee)
{
Class = wrappee;
}
public T Class { get; } // C# 6.0 Syntax, otherwise add "private set;"
}
Then you can create a wrapper at runtime with
Type typeToBeWrapped = objToBeWrapped.GetType();
Type genericWrapper = typeof(Wrapper<>);
Type constructedWrapper = genericWrapper.MakeGenericType(typeToBeWrapped);
object obj = Activator.CreateInstance(constructedWrapper, objToBeWrapped);

Inconsistent accessibility error declaring public class method with internal type (C#)?

I have a JSON class object that is an internal class. I'd like to keep it that way to keep other code from trying to create objects of that type since I only want the JSON deserialization code to do that. I can use the class type as a variable, but if I try to return an object of that type I get an inconsistent accessibiliy compiler error because the method is public and the class is internal.
What is the best way to resolve this situation? I guess I could create an interface for the internal class and pass that around, but that means I have to create extra baggage for every JSON class I am using and I'm using a lot of them.
EDIT: I made the change suggested by Jon Skeet and the problem went away. I got into this problem because of the habit of declaring my classes public by default. I'm pointing this out for others that are doing the same thing.
// The internal class.
internal class JsonPetShelters
{
[JsonProperty("#encoding")]
public string Encoding { get; set; }
[JsonProperty("#version")]
public string Version { get; set; }
[JsonProperty("petfinder")]
public Petfinder Petfinder { get; set; }
}
// This method gets the inconsistent accessibility error since
// JsonPetShelters is an internal class.
public JsonPetShelters GetShelters()
{
// For example purposes only
return null;
}
What is the best way to resolve this situation?
You either need to make JsonPetShelters public, or make GetShelters() internal.
So you want to be able to call this method from a different assembly? If so, how would you expect callers to use it, without understanding the return type? If not, why is the method public?
Once you've worked out what you want do achieve in a consistent way, making the change should be simple.
EDIT: As you've said you only want code in the same assembly to be able to call the method, just change it to be internal:
internal JsonPetShelters GetShelters()
{
...
}
The compile-time error will go away, and you'll no longer be exposing a member you didn't want to expose in the first place.
You can declare the class Constructor explicitly and make it internal, while the class remains public.
That will allow every assembly to use the class, but only your assembly can create instances.
public class JsonPetShelters
{
[JsonProperty("#encoding")]
public string Encoding { get; set; }
[JsonProperty("#version")]
public string Version { get; set; }
[JsonProperty("petfinder")]
public Petfinder Petfinder { get; set; }
internal JsonPetShelters() {}
}

To abstract, or not to abstract

thanks in advance for reading this. I don’t fully understand how/when to use abstracts so I am trying to think about it each project I work on to see if it will all click some day Smile | :)
Also, the mix of accessibility levels (private, protected, internal) with keywords static, abstract, and override tend to leave me a little confused. How do I define this method/property/class....
It's not all a big mystery to me but some projects have me coding in circles when dealing with these topics.
With that said,
I have an application that reads an XML document and outputs text and image files. I’m also storing all of the information in a database. I have it working nicely.
The XML has a standard implementation with required fields and is used by multiple organizations to submit data to my app. All organizations should use (at least) the required nodes/elements that are outlined in the XML implementation guide.
So, I want to have a default data object type to be able to derive a specific organization’s data type for required elements. (If this object is going to be used, these are the fields that must be implemented).
If the org. just uses the default requirements, I can use the default object. If they use additional (optional) fields, I’ll have to create a new type inheriting the default type.
My first thought was to use and abstract class that had protected properties for my bare minimum requirements:
public abstract partial class AbstractDataObject
{
protected string DataObjectName;
protected DateTime? DataObjectDate;
etc...
}
Then, if the organization just uses the required elements of the node and no optional elements, I can use a “default” object.
internal partial class DefaultDataObject : AbstractDataObject
{
public new string DataObjectName { get; set; }
public new DateTime? DataObjectDate { get; set; }
etc...
}
But, if an organization uses optional fields of the required node, I can use a derived organization data object.
internal sealed partial class OranizationDataObject : AbstractDataObject
{
public new string DataObjectName { get; set; }
public new DateTime? DataObjectDate { get; set; }
etc...
//Optional fields used by this organization
public string DataObjectCode { get; set; }
etc...
}
Do I need the abstract class? It seems to me I can just have a DefaultDataObject (something like):
internal partial class DefaultDataObject
{
public virtual string DataObjectName { get; set; }
public virtual DateTime? DataObjectDate { get; set; }
etc...
}
And then:
internal sealed partial class OranizationDataObject : DefaultDataObject
{
public override string DataObjectName { get; set; }
public override DateTime? DataObjectDate { get; set; }
etc...
//Optional fields used by this organization
public string DataObjectCode { get; set; }
etc...
}
I’m just really trying to understand how to define these objects so I can reuse them per organization. Both ways seem to work, but I am hoping to understand how to define them properly.
Getting the XML into above objects:
public DefaultDataObject ExtractXmlData(XContainer root)
{
var myObject = (from t in root.
Elements("ElementA").Elements("ElementB")
select new DefaultDataObject()
{
DataObjectName = (String)t.Element("ChildElement1"),
DataObjectDate =
Program.TryParseDateTime((String)
t.Elements("ChildElement2")
.ElementAtOrDefault(0)
),
etc....
OR
public OranizationDataObject ExtractXmlData(XContainer root)
{
var myObject = (from t in root.
Elements("ElementA").Elements("ElementB")
select new OranizationDataObject()
{
DataObjectName = (String)t.Element("ChildElement1"),
DataObjectDate = Program.TryParseDateTime(
(String)t.Elements("ChildElement2")
.ElementAtOrDefault(0)),
DataObjectCode = (String)t.Element("ChildElement3"),
etc....
Again, thanks for reading. Don't forget to tip your wait staff....
Joe
First of all, your base class doesn't need to be abstract if it's a plain DTO class. If you don't have any functionality that needs to be implemented differently by derived classes, you can simply make it a plain base class which will hold common properties.
Next, there is no point in declaring properties in the base class (abstract in your case), if you are going to hide them (using the new keyword). You first code snippet of DefaultDataObject unnecessarily creates a bunch of new properties with the same name. Remove them completely - they are already defined in the base class.
[Edit] I didn't notice this initially, and #svick warned me, that your base class actually contained fields instead of properties, which makes me wonder why you needed to add the new keyword at all. I went over your code quickly and saw them as properties. In any case, you should never expose public fields - at least change them to auto-implemented properties by adding the { get; set; } block.
In other words, this would simply work:
// this doesn't need to be abstract.
// just put all the common stuff inside.
public class BaseDO
{
// as svick pointed out, these should also be properties.
// you should *never* expose public fields in your classes.
public string Name { get; set; }
public DateTime? Date { get; set; }
}
// don't use the new keyword to hide stuff.
// in most cases, you won't need that's behavior
public class DerivedDO : BaseDO
{
// no need to repeat those properties from above,
// only add **different ones**
public string Code { get; set; }
}
As a side note, but nevertheless important IMHO, you should simplify naming (and make it more clearer what your code does). There is no need to repeat "DataObject" in every property name, for example. But since your code is probably only a simplified version, it doesn't matter.
Lastly, have you heard of XmlSerializer? You don't need to traverse the XML elements manually. It is enough to call XmlSerializer to both serialize and deserialize your data.
Everything I need to know I learned from Sesame Street
Scrub your class design hard to make sure you've identified everything that is the same and different. Play computer, so to speak, with your classes and see how they do the same, different, or the same thing but in different ways.
What is the same, different, same but differently will likely change as you play computer.
Think in general terms of the two pillars of OO Classes. Polymorphism and Inheritance
As you do the above that is. Not so much in terms of C# implementation per se.
How things clump into same vs. different will help drive implementation
And it's all relative.
More of same default behavior? Perhaps a concrete base class instead of abstract.
More of same thing, but differently? Perhaps an abstract class instead of concrete base class.
A default way of doing x? Perhaps a virtual method.
Everyone does the same thing, but no two the same way? A delegate perhaps.
Implementation Suggestions
Make methods and fields protected as a default. Private does not get inherited. Designs change, stay flexible. If something just has to be private, fine.
virtual means you can change implementation in a sub class. It does not mean you must.
Folks seem to under-utilize delegates. They're super for polymorphic methods.
There is nothing wrong with public fields. What's the practical difference between a public field and a public auto-implemented property? Nothing. They both directly return (or set) the underlying value. So what's the point of even bothering with properties? If you want to publicly expose an underlying value differently than it's "natural" state. For example, returning a number in a specific format. And of course you can have different properties for the same field.
A Property can have a get without a set. Or vice versa. Also get and set can have different access levels. Often you'll see this as a public get and a protected (or private) set.
It depends on what the derived types will want to do. If they are going to use the default implementation and only expand on it somehow, then having the default class as the non-abstract base class is fine.
On the other hand, if they are most likely going to re-implement the functionality, you should have an abstract base class (or an interface) and a separate default class.
If you for some reason don't know which one is it, you can let the inheritors choose by having an abstract base class and leaving the default class unsealed.
Also, looking at your code, it seems you misunderstand what the various keywords do. Most of the time, you do not want to use new like this. What it does is to define another member with the same name, unrelated to the original one. Also, there's no reason to override something if you don't want to change it. So, if you expect that the derived classes won't have to reimplement the properties, you don't have to make them virtual at all.
An abstract class can already implement things that can be inherited
public abstract class DataObjectBase
{
public string DataObjectName { get; set; }
public DateTime? DataObjectDate { get; set; }
}
A concrete class can add new properties and methods
public class DerivedDataObject : DataObjectBase
{
public int NewProperty { get; set; }
}
The properties DataObjectName and DataObjectDate are already available in the new class, because they are automatically inherited from the base class.
If the abstract class defined an abstract member, however, you would have to implement it in the derived class.
Say the base class defines
public abstract void SomeMethod(string name);
The the derived class has to do this
public override void SomeMethod(string name)
{
...
}
If your base class does not have abstract members, it does not need to be abstract and can play the role of your default data object directly.
The keyword 'partial` is not needed here. It is only useful if you want to split one class into several pieces over several files.
The keyword new is wrong here. It is used to shadow an inherited member. This means that the inherited member will be hidden "behind" the new declaration. What you need, is to override. This does not hide a member, but provide an alternative implementation of the same member in the derived class.

Non-constructed generics as properties (eg. List<T>)

The Problem
It's something I came across a while back and was able to work around it somehow. But now it came back, feeding on my curiosity - and I'd love to have a definite answer.
Basically, I have a generic dgv BaseGridView<T> : DataGridView where T : class. Constructed types based on the BaseGridView (such as InvoiceGridView : BaseGridView<Invoice>) are later used in the application to display different business objects using the shared functionality provided by BaseGridView (like virtual mode, buttons, etc.).
It now became necessary to create a user control that references those constructed types to control some of the shared functionality (eg. filtering) from BaseGridView. I was therefore hoping to create a public property on the user control that would enable me to attach it to any BaseGridView in Designer/code: public BaseGridView<T> MyGridView { get; set; }. The trouble is, it doesn't work :-) When compiled, I get the following message:
The type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?)
Solutions?
I realise I could extract the shared functionality to an interface, mark BaseGridView as implementing that interface, and then refer to the created interface in my uesr control.
But I'm curious if there exists some arcane C# command/syntax that would help me achieve what I want - without polluting my solution with an interface I don't really need :-)
EDIT: For reference, I did try this innocent workaround: BaseGridView<object> MyGridView { get; set; }, and... it still isn't the answer: Cannot implicitly convert type 'InvoiceGridView' to 'BaseGridView<object>'.
Partial success (edit 2)
Ok, because covariance is only supported on interfaces, I admitted defeat and defined an interface (only showing some of it):
public interface IBaseGridView<out T> where T : class
{
bool ScrollTo(Predicate<T> criteria);
bool ScrollTo(T object);
}
I am now able to cast my beloved InvoiceGridView to an IBaseGridView<object> - which is awesome and I'm a happy boy again :-) However, the second ScrollTo is giving me trouble upon compilation:
Invalid variance: The type parameter 'T' must be contravariantly valid on 'GeParts.Controls.IBaseGridView.ScrollTo(T)'. 'T' is covariant.
I'm now having to modify the signature to ScrollTo(object o) - which isn't ideal but gets the job done. What suprised me was that the compiler complained about the second ScrollTo yet was happy with the first one. So it seems that one isn't allowed to pass instances of an out T, but using the type itself (eg. in Predicate<T>) is fine? Seems rather picky...
Since you wrote
But I'm curious if there exists some arcane C# command/syntax that would help me achieve what I want
I'd like to add that C# 4.0 makes it possible to substitute derived types for a base type using < out T > for covariance. So you could do
public BaseGridView<Object> MyGridView { get; set; }
So you get a well known type but you can return whatever BaseGridView you want. The only catch is unfortunately that covariance is only allowed on interfaces! :(
C# doesn't support generic properties to my knowledge. Your options are either to create generic methods or to make the generic type part of your class definition.
For example:
public BaseGridView<T> GetMyGridView<T>() { ... }
public void SetMyGridView<T>(T gridView) { ... }
or
class MyClass<T> {
public BaseGridView<T> MyGridView { get; set; }
}
The following would probably work:
public BaseGridView<T> MyGridView<T> { get; set; }
The problem with your original answer is that the type parameter has to appear on the method or class declaration, not just on the return value.
Note that the compiler cannot infer generic types from return values, so you'll be required to specify T in every call to MyGridView.
I just tried whipping together some code and it works fine for me:
public class A<T> where T : class
{
public virtual A<T> ARef
{
get { return default(A<T>); }
}
}
public class B : A<B>
{
public override A<B> ARef
{
get
{
return base.ARef;
}
}
}
Shouldn't it be like this:
public BaseGridView MyGridView { get; set; }
public BaseGridView<T> GetMyGridView<T> { return whatever; }
public void SetMyGridView<T>( BaseGridView<T> bgv) { whatever = bgv; }
??
Edited. Matthew is right, Properties may not be generic. You would have to use a getter/setter.

How to make 2 incompatible types, but with the same members, interchangeable?

Yesterday 2 of the guys on our team came to me with an uncommon problem. We are using a third-party component in one of our winforms applications. All the code has already been written against it. They then wanted to incorporate another third-party component, by the same vender, into our application. To their delight they found that the second component had the exact same public members as the first. But to their dismay, the 2 components have completely separate inheritance hierarchies, and implement no common interfaces. Makes you wonder... Well, makes me wonder.
An example of the problem:
Incompatible Types http://www.freeimagehosting.net/uploads/f9f6b862f1.png
public class ThirdPartyClass1
{
public string Name
{
get
{
return "ThirdPartyClass1";
}
}
public void DoThirdPartyStuff ()
{
Console.WriteLine ("ThirdPartyClass1 is doing its thing.");
}
}
public class ThirdPartyClass2
{
public string Name
{
get
{
return "ThirdPartyClass2";
}
}
public void DoThirdPartyStuff ()
{
Console.WriteLine ("ThirdPartyClass2 is doing its thing.");
}
}
Gladly they felt copying and pasting the code they wrote for the first component was not the correct answer. So they were thinking of assigning the component instant into an object reference and then modifying the code to do conditional casts after checking what type it was. But that is arguably even uglier than the copy and paste approach.
So they then asked me if I can write some reflection code to access the properties and call the methods off the two different object types since we know what they are, and they are exactly the same. But my first thought was that there goes the elegance. I figure there has to be a better, graceful solution to this problem.
My first question was, are the 2 third-party component classes sealed? They were not. At least we have that.
So, since they are not sealed, the problem is solvable in the following way:
Extract a common interface out of the coinciding members of the 2 third-party classes. I called it Icommon.
public interface ICommon
{
string Name
{
get;
}
void DoThirdPartyStuff ();
}
Then create 2 new classes; DerivedClass1 and DerivedClass2 that inherit from ThirdPartyClass1 and ThirdPartyClass2 respectively. These 2 new classes both implement the ICommon interface, but are otherwise completely empty.
public class DerivedClass1
: ThirdPartyClass1, ICommon
{
}
public class DerivedClass2
: ThirdPartyClass2, ICommon
{
}
Now, even though the derived classes are empty, the interface is satisfied by the base classes, which is where we extracted the interface from in the first place.
The resulting class diagram looks like this.
alt text http://www.freeimagehosting.net/uploads/988cadf318.png
So now, instead of what we previously had:
ThirdPartyClass1 c1 = new ThirdPartyClass1 ();
c1. DoThirdPartyStuff ();
We can now do:
ICommon common = new DerivedClass1 ();
common. DoThirdPartyStuff ();
And the same can be done with DerivedClass2.
The result is that all our existing code that referenced an instance of ThirdPartyClass1 can be left as is, by just swapping out the ThirdPartyClass1 reference for a ICommon reference. The ICommon reference could then be given an instance of DerivedClass1 or DerivedClass2, which of course in turn inherits from ThirdPartyClass1 and ThirdPartyClass2 respectively. And all just works.
I do not know if there is a specific name for this, but to me it looks like a variant of the adaptor pattern.
Perhaps we could have solve the problem with the dynamic types in C# 4.0, but that would have not had the benefit of compile-time checking.
I would be very interested to know if anybody else has another elegant way of solving this problem.
If you're using .Net 4 you can avoid having to do alot of this as the dynamic type can help with what you want. However if using .Net 2+ there is another (different way) of achieving this:
You can use a duck typing library like the one from Deft Flux to treat your third party classes as if they implemented an interface.
For example:
public interface ICommonInterface
{
string Name { get; }
void DoThirdPartyStuff();
}
//...in your code:
ThirdPartyClass1 classWeWishHadInterface = new ThirdPartyClass1()
ICommonInterface classWrappedAsInterface = DuckTyping.Cast<ICommonInterface>(classWeWishHadInterface);
classWrappedAsInterface.DoThirdPartyStuff();
This avoids having to build derived wrapper classes manually for all those classes - and will work as long as the class has the same members as the interface
What about some wrappers?
public class ThirdPartyClass1 {
public string Name {
get {
return "ThirdPartyClass1";
}
}
public void DoThirdPartyStuff() {
Console.WriteLine("ThirdPartyClass1 is doing its thing.");
}
}
public interface IThirdPartyClassWrapper {
public string Name { get; }
public void DoThirdPartyStuff();
}
public class ThirdPartyClassWrapper1 : IThirdPartyClassWrapper {
ThirdPartyClass1 _thirdParty;
public string Name {
get { return _thirdParty.Name; }
}
public void DoThirdPartyStuff() {
_thirdParty.DoThirdPartyStuff();
}
}
...and the same for ThirdPartyClass2, then you use the wrapper interface in all your methods.
Add an interface. You could add one wrapper (that implements the interface) for each of the 3rd parties.
Anyway, if you have the code of those 3rd parties, you could skip the wrapper thing and directly implement the interface. I'm quite sure you don't have the source, though.

Categories

Resources