C++/cli interface with properties not usable from c# - c#

Cli interface looks like this:
using namespace System::Timer
namespace Interfaces
{
public interface class ITimerProvider
{
property Timer AppTimer
{
Timer get();
}
}
}
Getting to a c# class deriving from that interface and using "implement interface" from right-click menu in VS2013, it creates:
public void get_AppTimer(ref Timer value)
{
throw new NotImplementedException();
}
The compiler complains "MyProject does not implement interface member MyCLIProject.Interfaces.ITimerprovider.get_AppTimer()"
It does so, even when it has put it inside by itself.

Hans has given the answer. Correcting interface declaration leads to expected auto-generated code and the project compiles fine:
property Timer^ AppTimer
{
Timer^ get();
}

I think this might be due to Visual Studio not generating the code correctly for you.
While technically properties are just syntactic sugar for the methods get_propertyName() and set_PropertyName(), you don't actually write those methods in C# when implementing a property. The correct C# code for implementing the property would be this:
class MyProject
{
public Timer AppTimer
{
get
{
// return the value here
}
}
}
If you change your code to something like this, that should fix the error.

Related

Raising warnings based on class attributes

Here is some code:
class Program
{
static void Main(string[] args)
{
MyClass class1 = new MyClass();
MyOtherClass class2 = new MyOtherClass();
Helper.UseAttribute<MyClass>(class1);
//Raise a warning to tell the developer that they cannot use this class
//as there is no property with the specified attribute.
Helper.UseAttribute<MyOtherClass>(class2);
}
}
public class MyAttribute : System.Attribute { }
class MyClass
{
[MyAttribute]
public string SomethingAwesome { get; set; }
}
class MyOtherClass
{
public string SomethingElseWhichIsAlsoPrettyAwesome { get; set; }
}
static class Helper
{
public static void UseAttribute<T>(T sender)
{
//Do something with the property that has MyAttribute
//If there isn't a property with this attribute, then raise
//a warning.
}
}
In an ideal scenario, I want to restrict a developer from passing classes to a method which do not have a certain attribute.
I am aware that I can use an interface, or a base class of some description, however the question really is whether something like the example above is possible.
If you're happy to either use the VS 2015 preview or wait until VS 2015 is out, you can use Roslyn for this.
You'd write a DiagnosticAnalyzer class, probably registering a syntax node analyzer to specifically look for invocations of Helper.UseAttribute<T>. When you find such a use, you'd find the symbol for T and check whether there are any properties with the MyAttribute attribute applied to it, and raise a warning if not. This warning will be shown in Visual Studio itself, as well as applying on CI builds (assuming you register the analyzer assembly appropriately).
It takes a while to get started with the Roslyn diagnostic APIs, but once you're used to it, it's really powerful.
Of course, another option is to throw an exception at execution time, and rely on there being unit tests around all callers so that you'd be able to catch it when they fail :) You should probably do that as well as adding compile-time support via Roslyn.
Best you can do right now is to handle it on runtime (and throw an exception or something). On design-/compiletime I think there is no possibility yet.
public static void UseAttribute<T>(T sender)
{
var hasAttribute = typeof(T).GetProperties().Any(prop => Attribute.IsDefined(prop, typeof(MyAttribute)));
if (!hasAttribute)
throw new Exception("Does not contain attribute");
}

No constructors defined

I have some code base which has is calling the following:
SetHazardDataService();
namespace Analytics.Foo.DataServices
{
class HDB:IDataService
{
}
}
With a member function declared in another class/file
using Analytics.Foo.DataServices
public void MyDataService()
{
var DbDataSvc = new HDB();
}
originally, I see the same definition used elsewhere but with (no idea if that works):
protected void MyDataService()
I included the public method in my class
I'm now trying to recreate that functionality, but I get the following issue:
The type Analytics.Foo.DataServices.HDB' has no constructors defined
I'm not sure what the issue is - any suggestions for why this is the case. There is no constructor that I can see. Plus I'm not able to see the other code working/but it doesn't give the same issue.
You need to create a constructor to class HDB, like this:
namespace Analytics.Foo.DataServices
{
class HDB:IDataService
{
public HDB()
{
}
}
}

Why is the constructor of a generic class with a default-valued enum parameter not able to call protected methods of that class?

A simple test case:
using System;
public class Test<T>
{
public enum TestEnum
{
A,
B
}
public Test (TestEnum a = TestEnum.A)
{
DoSomething ();
}
protected void DoSomething()
{
}
}
The compiler (this is using Mono in a Unity3D project, .NET4.0 target) gives an error on the call in Test() to DoSomething(). If I remove the default parameter on TestEnum a, it builds just fine. MonoDevelop wants to call the default parameter TestEnum<>.A, but that doesn't compile, neither does TestEnum<T>.A (obviously I wouldn't have expected these to work but using MonoDevelop's autocomplete that's what I get).
EDIT: the specific error is: the name DoSomething doesn't exists in the current context
As said so in the comments, this is a compiler bug.
It seems as your Mono development environment doesn't really like the protected keyword.
Use {public,private} for now.

How to hide public methods from IntelliSense

I want to hide public methods from the IntelliSense member list. I have created an attribute that, when applied to a method, will cause the method to be called when its object is constructed. I've done this to better support partial classes. The problem is that in some environments (such as Silverlight), reflection cannot access private members, even those of child classes. This is a problem since all of the work is done in a base class. I have to make these methods public, but I want them to be hidden from IntelliSense, similar to how the Obsolete attribute works. Frankly, because I am anal about object encapsulation. I've tried different things, but nothing has actually worked. The method still shows up in the member drop-down.
How do I keep public methods from showing up in IntelliSense when I don't want them to be called by clients? How's that for a real question, Philistines! This can also apply to MEF properties that have to be public though sometimes you want to hide them from clients.
Update:
I have matured as a developer since I posted this question. Why I cared so much about hiding interface is beyond me.
Using the EditorBrowsable attribute like so will cause a method not to be shown in IntelliSense:
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public void MyMethod()
{
}
You are looking for EditorBrowsableAttribute
The following sample demonstrates how to hide a property of a class from IntelliSense by setting the appropriate value for the EditorBrowsableAttribute attribute. Build Class1 in its own assembly.
In Visual Studio, create a new Windows Application solution, and add a reference to the assembly which contains Class1. In the Form1 constructor, declare an instance of Class1, type the name of the instance, and press the period key to activate the IntelliSense drop-down list of Class1 members. The Age property does not appear in the drop-down list.
using System;
using System.ComponentModel;
namespace EditorBrowsableDemo
{
public class Class1
{
public Class1()
{
//
// TODO: Add constructor logic here
//
}
int ageval;
[EditorBrowsable(EditorBrowsableState.Never)]
public int Age
{
get { return ageval; }
set
{
if (!ageval.Equals(value))
{
ageval = value;
}
}
}
}
}
To expand on my comment about partial methods. Try something like this
Foo.part1.cs
partial class Foo
{
public Foo()
{
Initialize();
}
partial void Initialize();
}
Foo.part2.cs
partial class Foo
{
partial void Initialize()
{
InitializePart1();
InitializePart2();
InitializePart3();
}
private void InitializePart1()
{
//logic goes here
}
private void InitializePart2()
{
//logic goes here
}
private void InitializePart3()
{
//logic goes here
}
}

Is it possible to write a extension method for an abstract class

Why I'm unable to extend an abstract class. Is there any work around to achieve this?
In silverlight, Enum.GetNames is missing. So, I would like to extend it and have it in my utility assembly. By then, got into this.
The problem here is not that you can't add an extension method to an abstract class (you can - you can add an extension method to any type) - it's that you can't add a static method to a type with extension methods.
Extension methods are static methods that present themselves in C# as instance methods. But they're still static. Adding a static method to a type requires the ability to redefine the type, which you can only do if you have the source code :)
Best bet, if you want this method, is to write your own static and see if you can perhaps rip the code out of reflector.
However, it's entirely possible that it's not there because it's physically not supported in Silverlight (I don't know - I haven't investigate)
EDIT
Following on from your comment - and I hope that I've understood you here - I think what you want to be able to do is something like this (targetting object to prove the point):
public static class ExtraObjectStatics
{
public static void NewStaticMethod()
{
}
}
public class Test
{
public void foo()
{
//You can't do this - the static method doesn't reside in the type 'object'
object.NewStaticMethod();
//You can, of course, do this
ExtraObjectStatics.NewStaticMethod();
}
}
If you think about it - of course you can't inject new static methods into an existing type because, like I said in paragraph two, you have to be able to recompile the underlying type; and there simply is no way around that.
What you can do is (and I don't actually recommend this - but it's an option) create yourself a new type called Enum and place it inside a new namespace:
namespace MySystem
{
public class Enum
{
public static string[] GetNames()
{
//don't actually know how you're going to implement it :)
}
}
}
And now - when you want to use it, what you can't do is this:
using System;
using MySystem;
namespace MyCode
{
public class TestClass
{
public static void Test()
{
Enum.GetNames(); //error: ambiguous between System and MySystem
}
}
}
Because the using in the outermost scope to both 'System' and 'MySystem' will cause the compiler not to be able to resolve the correct Enum type.
What you can do, however, is this:
using System;
namespace MyCode
{
using MySystem; //move using to inside the namespace
public class TestClass
{
public static void Test()
{
//will now work, and will target the 'MySystem.Enum.GetNames()'
//method.
Enum.GetNames();
}
}
}
Now, code within that namespace (within that file only) will always resolve Enum to the one in your namespace because that's the nearest using directive in terms of scope.
So, you can think of this as overriding the whole Enum type for the benefit of a given namespace that includes a using MySystem; in it.
But, it does exactly that - it replaces the existing System.Enum with MySystem.Enum - meaning that you lose all the members of the System.Enum type.
You could get around this by writing wrapper methods in your Enum type around the System.Enum versions - making sure that you fully-qualify the type as System.Enum.
Having looked at the implementation of the GetNames method in Reflector - it relies on internal data that I don't think you're going to be able to build... but I would be very interested to hear if you are actually able to reproduce the method in Silverlight.
public abstract class Foo
{
public abstract void Bar();
}
public static class FooExtensions
{
// most useless extension method evar
public static void CallBar(this Foo me)
{
me.Bar();
}
}
Sure, no problem.

Categories