We are using a 3rd party assembly which has a problematic method. Is there some way to alert our developers that the method should not be used, preferably at compile time but run-time is ok too. Something like an Obsolete attribute but for another assembly. I can't override the method because it's not virtual.
The only way I can see that this is possible is to wrap the API in your own assembly and get the developers to use your assembly instead of the provided one.
using MyAPI;
public class MyWrapper
{
private MyAPI _api;
public MyWrapper()
{
_api = new MyAPI(); //Especially if you want to do some inits
}
public void APIMethod()
{
_api.APIMethod();
}
}
My using the same method names, it will allow your developers to just replace the instantiation of the object with the new class, or even more cheekily, call the class the same thing and change the namespace.
Then, you can either omit the offending method(s) or mark them as obsolete.
You could even use the T4 templates to generate the code for you so you can regenerate if the API changes. If you use reflection, you may not even have to write the T4...
For nmore info on T4 - https://msdn.microsoft.com/en-us/library/dd820614.aspx
Hope this was useful.
Related
I plan to give method calling privileges to certain classes in my program using Attributes but I just have no clude how to.
For example, here is what I want my Customer class to look like:
[ForbiddenMethodsAttr(listOfMyForbiddenMethods)]
public class Customer
{
public Customer { }
}
And if I want to call a given function, the intellisense should warm me that I can't, The reason I want to do this is because calling those functions may cause some issues and not I'm the only one who will code this project but some friends as well. So if it is possible to write such an attribute, how to do it?
You could mark the methods as obsolete and then anyone calling them will get a compiler warning (though not error). Its not elegant, but neither is attempting to restrict method calls without using scoping conventions.
I've built a reusable Class Library to encapsulate my Authentication logic. I want to be able to reuse the compiled *.dll across multiple projects.
What I've got works. But, something about how I'm making the reference, or how my Class Library is structured isn't quite right. And I need your help to figure out what I'm doing-wrong/not-understanding...
I've got a Class Library (Authentication.dll) which is structured like this:
namespace AUTHENTICATION
{
public static class authentication
{
public static Boolean Authenticate(long UserID, long AppID) {...}
//...More Static Methods...//
}
}
In my dependent project I've added a reference to Authentication.dll, and I've added a using directive...
using AUTHENTICATION;
With this structure I can call my Authenticate method, from my dependent project, like so...
authentication.Authenticate(1,1)
I'd like to be able to not have to include that "authentication." before all calls to methods from this Class Library. Is that possible? If so, what changes do I need to make to my Class Library, or how I'm implementing it in my dependent project?
In C# a function cannot exist without a class. So you always need to define something for it, being a class for a static method or an object for an object method.
The only option to achieve that would be to declare a base class in the Authentication assembly from which you inherit in the dependent projects.
You could expose Authenticate as a protected method (or public works too), and call it without specifying the class name.
public class MyClassInDependentProject : authentication
{
public void DoSomething(int userId, long appId)
{
var success = Authenticate(userId, appId);
…
}
}
That said, you'll quickly find this to be a bad design. It conflates a cross-cutting concern with all sorts of other classes, and those classes are now precluded from inheriting from any other class.
Composition is a core principle of object-oriented programming, and we have the idiom "Favor composition over inheritance." This simply means that we break down complexity into manageable chunks (classes, which become instantiated as objects), and then compose those objects together to handle complex processing. So, you have encapsulated some aspect of authentication in your class, and you provide that to other classes compositionally so they can use it for authentication. Thinking about it as an object with which you can do something helps, conceptually.
As an analogy, think about needing to drill a hole in the top of your desk. You bring a drill (object) into your office (class). At that point, it wouldn't make sense to simply say "On," because "On" could be handled by your fan, your lamp, your PC, etc. (other objects in your class). You need to specify, "Drill On."
If you are making a class library in C# you should learn to use the naming conventions that exists: Design Guidelines for Developing Class Libraries
Here is how you should name namespaces: https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/interface
C# is also an object oriented language, hence the need of classes (using Authentication as you should name your class).
It also seems like the data source is hard coded. Your class library users (even if it's just you) might want to configure the data source.
Google about singleton and why it's considered to be an anti pattern today (in most cases).
You are obliged to use Class in order to invoke your method, just
When is static class just NameClass.Method
When is not static, you must create instance, ClassName ob = new ClassName(); ob.Method();
The format of a call like this is class.method, and you really can't escape using the "class" moniker even with the "using" designation. Something has to "host" the function.
I don't think what you are asking for is possible without using the base class method Jay mentioned. If all you want is to simplify the syntax whenever you call Authenticate() however, this silly solution (adding an extra method in each class that needs to do authentication) may be just what you want:
private static void DoAuth(long UserID, long AppID){
authentication.Authenticate(UserID, AppID)
}
If the ID's are always the same within some context, you could also overload it:
private static void DoAuth(){
DoAuth(1,1)
}
Yes, this does mean you have to add more code wherever you want to do the authentication (that's why it's silly! ;) ). It does also however, also reduce this:
authentication.Authenticate(1,1);
...into this:
DoAuth();
I leave the cost / benefit analysis of this up to you..
I know I am some 3 years late but here goes nothing.
To keep your code cleaner and more readable you should create a new namespace for all the re-usable code that you want to have. Then in that namespace have the Authentication Class and Authenticate Function.
To use this you can easily set a using on your namespace and use the function as you are doing like
Authentication.Authenticate()
But to use
Authenticate()
by itself you can always do
using MyNamespace.Authentication;
and in your code use Authenticate Function directly.
protected static new void WhyIsThisValidCode()
{
}
Why are you allowed to override static methods?
Nothing but bugs can come from it, it doensn't work as you would think.
Take the following classes.
class BaseLogger
{
protected static string LogName { get { return null; } }
public static void Log(string message) { Logger.Log(message, LogName); }
}
class SpecificLogger : BaseLogger
{
protected static string LogName { get { return "Specific"; } }
}
this is alowed, and the code
SpecificLogger.Log("test");
is altso alowed, but it doesn't do what you would think by looking at the code.
it calls Logger.Log with LogName = null.
So why is this allowed?
The new keyword does not override a method. It instead creates a new method of the same name which is independent of the original. It is not possible to override a static method because they are not virtual
You're not overriding it, you're hiding it. A normal method would exhibit exactly the same behavior so there is nothing specific to static methods here.
Hiding is only useful in a few cases. The one where I came across most often is making the return type more specific in a derived class. But I never had that occur with static methods.
One area where static functions with a certain name might be useful is if you use reflection and want to get information on each class by returning it from a method. But of course in most cases an attribute fits better.
And it's not likely to create bugs since your code produces a compiler-warning:
Warning 'StaticHiding.SpecificLogger.LogName' hides inherited member 'StaticHiding.BaseLogger.LogName'. Use the new keyword if hiding was intended.
And if you use new you should know what you're doing.
Others have pointed out that this isn't overriding, but that still leaves your original question: why are you able to do it? (But the question is really "why can you hide static methods".)
It's an inevitable feature of supporting the independent versioning of component that contain base classes and components that use those base classes.
For example, imagine that component CompB contains the base class, and some other component CompD contains a derived class. In version 1 of CompB, there might not have been any property called LogName. The author of CompD decides to add a static property called LogName.
The critical thing to understand at this point is that the author of v1 of CompD was not intending to replace or hide any feature of the base class - there was no member called LogName in the base class when they wrote that code.
Now imagine that a new version of the CompB library is released. In this new version, the author added a LogName property. What's supposed to happen in CompD? The options appear to be:
CompD no longer works because the LogName it introduces clashes with the LogName added to CompB
Somehow make the CompD's LogName replace the base CompB LogName. (It's not actually remotely clear how this could work with statics. You could envisage this with non-statics though.)
Treat the two LogName members as being completely different members that happen to have the same name. (In reality, they don't - they're called BaseLogger.LogName and SpecificLogger.LogName. But since in C# we don't always need to qualify the member name with the class, it looks like they're the same name.)
.NET chooses to do 3. (And it does that with both statics and non-statics. If you want behaviour 2 - replacement - with non-statics, then the base has to be virtual and the derived class has to mark the method as override to make it clear that they were deliberately overriding a method in the base class. C# will never make a derived class's method replace a base class's method unless the derived class explicitly stated that this is what they wanted.) This is likely to be safe because the two members are unrelated - the base LogName didn't even exist at the point where the derived one was introduced. And this is preferable to simply breaking because the latest version of the base class introduced a new member.
Without this feature, it would be impossible for new versions of the .NET Framework to add new members to existing base classes without that being a breaking change.
You say that the behaviour isn't what you expect. Actually it's exactly what I'd expect, and what you'd probably want in practice. The BaseLogger has no idea that the SpecificLogger has introduced its own LogName property. (There's no mechanism by which it could because you cannot override static methods.) And when the author of SpecificLogger wrote that LogName property, remember that they were writing against v1 of BaseLogger which didn't have a LogName, so they weren't intending that it should replace the base method either. Since neither class wants replacement, clearly replacement would be the wrong thing.
The only scenario in which you should ever end up in this situation is because the two classes are in different components. (Obviously you can contrive a scenario when they're in the same component, but why would you ever do that? If you own both pieces of code and release them in a single component, it'd be mad ever to do this.) And so BaseLogger should get its own LogName property, which is exactly what happens. You may have written:
SpecificLogger.Log("test");
but the C# compiler sees that SpecificLogger doesn't provide a Log method, so it turns this into:
BaseLogger.Log("test");
because that's where the Log method is defined.
So whenever you define a method in a derived class that isn't attempting to override an existing method, the C# compiler indicates this in the metadata. (There's a "newslot" setting in the method metadata that says, this method is meant to be brand new, unrelated to anything in the base class.)
But this gives you a problem if you want to recompile CompD. Let's say you've got a bug report due to some entirely unrelated bit of code and you need to release a new version of CompD. You compile it against the new verison of CompB. If the code you've written wasn't allowed, you wouldn't actually be able to - old code that's already compiled would work, but you wouldn't be able to compile new versions of that code, which would be a bit mad.
And so, to support this (frankly somewhat obscure) scenario, they allow you to do this. They generate a warning to let you know that you've got a naming clash here. You need to supply the new keyword to get rid of it.
This is an obscure scenario, but if you want to support inheritance across component boundaries, you need this, otherwise the addition of new public or protected members on a base class would invariably be a breaking change. That's why this is here. But it's bad practice ever to rely on it, hence the fact that you get a compiler warning. The use of the new keyword to get rid of the warning should only ever be a stopgap.
The bottom line is this: this feature exists for one reason only, and that's to get you out of a hole in situations where a new version of some base class has added a member that didn't previously exist, and which clashes with a member that's already on your derived class. If that's not the situation you're in, don't use this feature.
(I think they should actually issue an error rather than a warning when you leave out new, to make this more clear.)
Static methods and fields do not belong to class instances but to class definitions. Static methods do not play part in the virtual dispatching mechanism and are not part of the virtual method table.
They are just methods and fields on that specific class.
It may look like the methods and fields are "inherited" because you can do SpecificLogger.Log(), but that is just something to keep you from having to refer to the base class all the time.
Static methods and fields really are just global methods and fields, just the OO kind.
for my surprise following code is allowed and compiles without any error on .net Framework 4.5.1, VS 2013.
class A
{
public static void Foo()
{
}
}
class B : A
{
}
class Program
{
static void main(string[] args)
{
B.Foo();
}
}
You aren't overriding the property in the base class, but instead hiding it. The actual property used at runtime depends on what interface you're working against. The following example illustrates:
SpecificLogger a = new SpecificLogger();
BaseLogger b = new SpecificLogger();
Console.Write(a.Log); // Specific
Console.Write(b.Log); // null
In your code the Log method is actually working against the BaseLogger interface - because the Log method is part of the BaseLogger class.
Static methods and properties can not be overridden, and when you want to hide a property you should use the new keyword to denote that you're hiding something.
I'd like to override a class method without inheriting the base class because it'd take a lot of time and modifications and, therefore, more and more tests. It's like this:
class TestClass{
public void initialMethod(){
...
}
}
And somewhere on the code, I'd like to do something like this:
public testMethod()
{
return;
}
test(){
changeMethod(TestClass.initialMethod, testMethod);
}
And this changeMethod function would override the TestClass initialMethod so that it'd call testMethod instead.
Inheriting and overriding the method using normal practices is not an option, as this class A is a graphic component and, inhereting it (and changing it) would break lots of code.
Edit: We don't have the base code for the TestClass, so it's not an option to modify the code there defining the initialMethod as a delegate.
Edit 2: Since this is a graphical component, the designer added a lot of code automatically. If I were to inherit this code, I would have to replace all code added by the designer. That's why I wouldn't like to replace this component.
You need the Strategy pattern.
Main steps:
Create an interface with ie. Do() signature
Your initialMethod() should call a strategy.Do(), where strategy is type of your interface
Create a class that implements this interface. Do() is your testmethod now.
Inject into your main class an instance of this class
If the job it's not so big (let's say just a color replacement or something) then I agree with Jhonny D. Cano's solution with C# (anonymous)delegates.
Edit (after edit 2)
May - just as proof-of-concept - you should inherit the class and replace all references from base class to this new. Do this, and nothing else. If it works, you can think about the next steps (new methods or delegates etc.)
You need only a new checkout from your version control system, and if it maybe fails you can abandon it. It's worth trying.
Perhaps you can do it as a delegate.
class TestClass {
public Action myAction;
public void initialMethod(){
...
}
initialMethod
public TestClass() {
myAction = initialMethod;
}
}
and then on TestMethod
public testMethod()
{
return;
}
test() {
testClassInstance.myAction = testMethod;
}
I think your best bet might be to use a AOP framework like LinFu. There's a codeproject article explaining it:
Introducing LinFu, Part VI: LinFu.AOP – Pervasive Method Interception and Replacement for Sealed Types in Any .NET Language
If 'TestClass' is something you defined, you could replace the 'initialMethod' definition with a property and delegate which can then be set to any method with a given signature. (Even anonymous ones.)
class TestClass {
Action _myMethod;
Action MyMethod {
get { return _myMethod; }
set { _myMethod = value; }
}
var tc = new TestClass()
tc.MyMethod = () -> Console.WriteLine("Hello World!");
tc.MyMethod()
The above code is untested.
The short and simple answer is: if you can't adjust the base TestClass code, no, there's no way you can modify the class to replace a method by another. Once we started doing stuff like that, we'd be in a completely different kind of language, like JavaScript.
The longer answer is: it depends on who is calling the replaced method.
If it's other classes, see if you can't implement a Proxy in between them and the unmodifiable concrete class. Whether this is doable depends on whether that class implements interfaces, or is its own interface.
If it's the class itself, then your only option is to decompile and modify the class, at design time using Reflector (or equivalent tools), or at runtime using Reflection.Emit. However, you'd have to be hurting pretty badly to go this route, as it's sure to be painful and brittle.
Unfortunately you still haven't explained what you are trying do and why. Replacing methods on the go is powerful stuff in the languages that permit it directly... There might be mocking libraries that can be twisted sufficiently far to do the reflection stuff, but then you'd be skating on thin ice.
If you don't have the code use Extension Methods.
public void doSmth(this objectYOUWANT arg)
{
//Do Something
}
Here you use the principle Closed for Modification Open for Extension.
This will add functionality to the library you don't have the source code. It's very clean to do it this way.
Edition:
In FrameWork 3.5 there is something new called Extension Methods. These kind of methods adds functionality to a closed Assembly letting you Extend in functionality a closed dll/assembly.
To use this for example you have a dll that you import, that is called Graphics.dll (you have the reference on your project)
First of all you shoud create a new static class called for example Extension:
public static class Extensions
{
}
Second, you want to add extra functionality to a class contained in Graphics.dll named ChartGraph. You will do this:
public static class Extensions
{
public static void draw(this ChartGraph g)
{
// DO SOMETHING
}
}
Third, when you instantiate a new object from the graphics.dll you now will have the new method you have created:
ChartGraph myG = new ChartGraph();
myG.draw();
As you can see there you have added new functionality without much effort without recompiling the dll, this is good if you don't have the source code.
I created a separate assembly to contain common extension methods, the extension methods uses classes from System.Web.dll (and others).
When I then create a new project (Console Application) that references the Utilities.dll assembly that contains the extension methods, I do not need to add a reference to System.Web.dll to the new project if it does not use the extension methods that extends any class in the System.Web.dll assembly (for example System.Web.UI.Control).
When one of the extension methods will be a generic method everything continues to work as expected. But as soon as I add a constraint to the generic method that constraines it to a class in the System.Web.dll assembly the compiler will complain that my new project (Console Application) needs a reference to System.Web.dll even though the new project is still not using anything in that assembly.
In other words as long as I dont have a constraint on my generic methods everything compiles but as soon as I add a constraint the compiler complains.
An example of my extension methods assemble (compiled as a library Utilities.dll):
public static class StringExtensions
{
public static bool IsNullOrEmpty(this string value)
{
return string.IsNullOrEmpty(value);
}
}
public static class ControlExtensions
{
// If I remove the where clause it compiles
public static T FildChild<T>(this Control parent, string id)
where T : Control
{
throw new NotImplementedException();
}
}
And here is a new console application that won't compile (unless I also add a reference to System.Web.dll):
static void Main(string[] args)
{
bool isEmpty = "Hello World!".IsNullOrEmpty();
Console.ReadLine();
}
Update:
As Marc pointed out (below) puting the offending method in a separate namespace fixes the problem.
But the question still remains why is the constraint a problem while the type Control was already used as a parameter to the method. and why is the namespace the solution when I already use the using directive at the top.
well, yes! In order to compile, it needs to be able to resolve everything in the public/protected API. Otherwise it can't enforce the constraint. I imagine it needs to recognise the types to see if the extension method is a candidate for a method.
You could try placing the extension methods in a child namespace that has "Web" in it - at least then it won't spill into regular code. I've checked, and this fixes the issue. It is good practice to separate the namespaces of extension methods to allow the caller to control when they should be in scope.
In order to execute, it would also need to be able to resolve anything used internally but not exposed in the API. This is standard behavior.
#Marc gives you the why. I would suggest that as a good practice you break out anything that refers to web classes into yet another assembly, say Com.Company.Extensions.Web in addition to Com.Company.Extensions. Then you can include both in web projects and only the non-web extensions in other projects.